简体   繁体   English

C#相当于Java的通配符

[英]C#'s equivalent of Java's wildcard

If it exists, what is the C# equivalent of the following Java code: 如果存在,那么以下Java代码的C#等价物是什么:

new HashMap<Class<? extends BaseClass>, Integer>();

I currently use new Dictionary<Type, int>() , which is more like 我目前使用new Dictionary<Type, int>() ,这更像
new HashMap<Class<?>, Integer>() which is obviously not the same. new HashMap<Class<?>, Integer>()显然不一样。

(Ignore the differences between HashMap and Dictionary ) (忽略HashMapDictionary之间的差异)

Edit: To clarify, I am not trying to define a new class, simply create an instance of HashMap / Dictionary . 编辑:为了澄清,我不是要尝试定义一个新类,只需创建一个HashMap / Dictionary实例。

I believe you want to constrain type parameters to generic types - the where keyword is used for that: 我相信你想要将类型参数约束为泛型类型 - where关键字用于:

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. 编辑:您无法完全按照C#中的要求执行操作 - 您无法使用类型约束定义泛型类型的本地实例。 You can, however, pre-declare your constrained Dictionary type (like my example) and then create an instance of that type like so: 但是,您可以预先声明受约束的Dictionary类型(如我的示例),然后创建该类型的实例,如下所示:

// 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. 如果我误解它发表评论 - 我不深入了解Java。

There is no equivalent of the Java wildcard in C#. C#中没有Java通配符的等价物。 In Java, the type for types is Class<T> where T is the class itself. 在Java中,类型的类型是Class<T> ,其中T是类本身。 The equivalent in C# is the type Type , which is not generic . C#中的等价物是Type ,它不是通用的 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): 因此,你可以做的最好的就是拥有一个Dictionary<Type, int> ,如果它被封装在一个类中,你可以限制你在代码中放入字典的内容(所以它只是运行时检查):

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. 您甚至可以使用该逻辑实现自己的IDictionary

UPDATE 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 .) (还要实现EqualsGetHashCode ,只需委托给Type 。)

And then your dictionary becomes: 然后你的词典变成:

var d = new Dictionary<TypeWrapper<BaseClass>, int>();
d.Add(typeof(BaseClass), 2);
d.Add(typeof(Child), 3);

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
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM