C#'s equivalent of Java's wildcard

前端 未结 3 610
生来不讨喜
生来不讨喜 2021-01-21 04:53

If it exists, what is the C# equivalent of the following Java code:

new HashMap, Integer>();

I currently

相关标签:
3条回答
  • 2021-01-21 05:29

    There is no equivalent of the Java wildcard in C#. In Java, the type for types is Class<T> where T is the class itself. The equivalent in C# is the type Type, which is not generic. So it seems that the best you can do is to have, as you said, a Dictionary<Type, int>, and if it's encapsulated in a class you can restrict what you put in the dictionary in the code (so it will just be a runtime check):

    private Dictionary<Type, int> myDictionary = new Dictionary<Type, int>();
    public void Add(Type type, int number) {
       if (!typeof(BaseClass).IsAssignableFrom(type)) throw new Exception();
       myDictionary.Add(type, number);
    }
    

    You can even implement your own IDictionary with that logic.

    UPDATE

    Another runtime trick I can think of is to use a wrapper class for your types:

    public class TypeWrapper<T>
    {
        public Type Type { get; private set; }
        public TypeWrapper(Type t)
        {
            if (!typeof(T).IsAssignableFrom(t)) throw new Exception();
            Type = t;
        }
        public static implicit operator TypeWrapper<T>(Type t) {
            return new TypeWrapper<T>(t);
        }
    }
    

    (Also implement Equals and GetHashCode, just delegate to Type.)

    And then your dictionary becomes:

    var d = new Dictionary<TypeWrapper<BaseClass>, int>();
    d.Add(typeof(BaseClass), 2);
    d.Add(typeof(Child), 3);
    
    0 讨论(0)
  • 2021-01-21 05:31

    Was looking into this same problem and this poor man's checker is the best thing I could come up with:

    class MyValue {
        public Type Type { get; private set; }
    
        private MyValue(Type type)
        {
            this.Type = type;
        }
    
        public MyValue of<T>() where T : BaseClass
        {
            return new MyValue(typeof(T));
        }
    }
    
    IDictionary<int, MyValue> myDictionary = new Dictionary<int, MyValue>()
    {
        { 1, MyValue.of<SubClass1>(); },
        { 2, MyValue.of<SubClass2>(); },
        { 3, MyValue.of<NotSubClass>(); }, // this causes a compile error
    };
    
    0 讨论(0)
  • 2021-01-21 05:42

    I believe you want to constrain type parameters to generic types - the where keyword is used for that:

    class MyDict<TKey, TValue> : Dictionary<TKey, TValue> where TValue : SomeBaseClass
    {
        ...
    }
    

    Is this what you're asking for or am I misunderstanding your question?

    Edit: you cannot do exactly what you ask for in C# - you can't define an local instance of a generic type with a type constraint. You can, however, pre-declare your constrained Dictionary type (like my example) and then create an instance of that type like so:

    // SomeClass will have to inherit from SomeBaseClass
    MyDict<SomeClass> instance = new MyDict<SomeClass> ();
    

    I think this is close to what you're looking for. Post a comment if I misunderstand it - I don't know Java this deep.

    0 讨论(0)
提交回复
热议问题