How do you provide a default type for generics?

后端 未结 6 1427
醉梦人生
醉梦人生 2020-12-30 18:58

I have a class that currently has several methods that take integer parameters. These integers map to operations that the application can perform. I\'d like to make the clas

相关标签:
6条回答
  • 2020-12-30 19:38

    The compiler can infer the type arguments on methods most of the time based on the type of the arguments passed:

    public void DoSomething<T>(T test) {
    }
    

    can be called with

    DoSomething(4);                   // = DoSomething<int>(4);
    DoSomething(MyEnum.SomeValue);    // = DoSomething<MyEnum>(MyEnum.SomeValue);
    

    By the way, you can have non-generic overloads of a generic method too.

    0 讨论(0)
  • 2020-12-30 19:41

    You can't do it in the definition of the class:

    var foo = new MyGenericClass(); // defaults to integer... this doesn't work
    var bar = new MyGenericClass<MyEnum>(); // T is a MyEnum
    

    If really value the implicitness of the default type being int, you'll have to do it with a static factory method, although I don't see the value of it.

    public class MyGenericClass<T>
    {
        public static MyGenericClass<T> Create()
        {
            return new MyGenericClass<T>();
        }
        public static MyGenericClass<int> CreateDefault()
        {
            return new MyGenericClass<int>();
        }
    }
    

    See below for how you really don't benefit from the above.

    var foo = MyGenericClass<MyEnum>.Create();
    var bar1 = MyGenericClass.CreateDefault(); // doesn't work
    var bar2 = MyGenericClass<int>.CreateDefault(); // works, but what's the point
    

    If you want to take it even farther, you can create a static factory class that will solve this, but that's an even more ridiculous solution if you're doing it for no other reason than to provide a default type:

    public static class MyGenericClassFactory
    {
        public static MyGenericClass<T> Create<T>()
        {
            return new MyGenericClass<T>();
        }
        public static MyGenericClass<int> Create()
        {
            return new MyGenericClass<int>();
        }
    }
    
    var foo = MyGenericClassFactory.Create(); // now we have an int definition
    var bar = MyGenericClassFactory.Create<MyEnum>();
    
    0 讨论(0)
  • 2020-12-30 19:42

    The compiler can infer the type arguments on fields most of the time based on the type of the arguments passed:

    import lombok.Data;
    
    @Data
    public class MyClass<T> {
    
        private T myField;
    }
    

    can be used as,

    MyClass myClass = new MyClass();
    String abc = "hello world !";
    myClass.setMyField(abc);
    System.out.println("test generic class with generic field = " + myGenericClass.getMyField());
    

    and that should result into,

    test generic class with generic field = hello world !
    
    0 讨论(0)
  • 2020-12-30 19:43

    Keep your original version (non-generic version) and create a generic version of it.

    Then call the generic version from your non-generic version.

    void Main()
    {
    DoSomething(2);
    DoSomething(EnumValue);
    
    }
    
    public void DoSomething(int test) {
    DoSomething<int>(test);
    }
    
    // Define other methods and classes here
    public void DoSomething<T>(T test) {
    Console.WriteLine(test);
    }
    
    0 讨论(0)
  • 2020-12-30 19:45

    I'm sure you've moved on from this, however I was working through a similar issue and found this solution that uses a context of "using" I was not familiar with. They need to put it in their namespace, so its not completely perfect.

    namespace mygeneric
    {
        public class SecurityContext<T>
        {
    
        }
    }
    
    namespace mytest
    {
        using SecurityContext = mygeneric.SecurityContext<int>;
        using mygeneric;
    
        enum MyContexts
        {
            User,
            Admin
        }
        class MyTest
        {
            SecurityContext myDefaultContext;
            SecurityContext<MyContexts> mySpecialContext;
        }
    }
    
    0 讨论(0)
  • 2020-12-30 20:02

    So... why not use simple inheritance? Like:

    class MyGenericClass<T>
    {
    }
    
    class MyGenericClass : MyGenericClass<int>
    {
    }
    

    This way you can write both ways:

    var X = new MyGenericClass<string>();
    var Y = new MyGenericClass(); // Is now MyGenericClass<int>
    
    0 讨论(0)
提交回复
热议问题