C#相当于Java的通配符

时间:2012-10-12 19:20:07

标签: c# java generics

如果存在,那么以下Java代码的C#等价物是什么:

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

我目前使用new Dictionary<Type, int>(),更像是new HashMap<Class<?>, Integer>(),显然不一样。

(忽略HashMapDictionary之间的差异)

修改:为了澄清,我不是要尝试定义新类,只需创建HashMap / Dictionary的实例。

3 个答案:

答案 0 :(得分:3)

我认为您希望将类型参数约束为泛型类型 - where关键字用于:

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

这是你要求的还是我误解了你的问题?

编辑:您无法完全按照C#中的要求执行操作 - 您无法使用类型约束定义泛型类型的本地实例。但是,您可以预先声明受约束的Dictionary类型(就像我的示例),然后像这样创建该类型的实例:

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

认为这接近你正在寻找的东西。如果我误解它,发表评论 - 我不太了解Java。

答案 1 :(得分:3)

C#中没有等效的Java通配符。在Java中,类型的类型是Class<T>,其中T是类本身。 C#中的等价物是Type类型,不是通用的。所以你可以做的最好就是拥有一个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);
}

您甚至可以使用该逻辑实现自己的IDictionary

<强>更新

我能想到的另一个运行时技巧是为你的类型使用包装类:

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

(同时实施EqualsGetHashCode,只需委托给Type。)

然后你的词典变成:

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

答案 2 :(得分:0)

正在调查同样的问题,这个可怜的男人的检查器是我能想到的最好的东西:

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