声明具有有界类型的泛型字典
本文关键字:泛型 字典 声明 类型 | 更新日期: 2023-09-27 18:00:28
我需要声明一个以Type
为键、以实例为值的Dictionary
。
我需要将键类型限制为特定的类层次结构。
对于Java地图,我可以做如下操作:
Map<Class<? extends MySuperClass>, ? extends MySuperClass>
我如何在C#中实现这一点?
不要直接暴露Dictionary
,这样可以手动控制何时添加
public void AddToDictionary(Type key, object value)
{
if(!key.IsAssignableFrom(typeof(SomeBaseClass))
throw new ArgumentException("Must be an inherited from SomeBaseClass type");
dictionary.Add(key, value);
}
我认为Sinatr公开一个添加到字典而不是字典本身的方法是一个非常好的主意。唯一的缺点是没有编译时的安全性;如果某些代码添加了错误类型的对象,那么直到运行时才会发现。
然而,使用泛型,我们可以调整方法,以便添加对象是万无一失的:
public void AddToDictionary<T>(T value) where T: MySuperClass
{
dict.Add(typeof(T), value);
}
现在,编写一个添加了错误类型的对象却仍在编译的程序是不可能的。
您可以使用typeof
来获取类的类型,例如:
Map<System.Type, object>
我不确定你会如何强制执行这项延期。在添加到地图之前,这可能应该作为一个测试来进行。
您可以:
public class MyType<TBase>
{
private Type Value;
protected MyType()
{
}
public static implicit operator Type(MyType<TBase> type)
{
return type.Value;
}
public static implicit operator MyType<TBase>(Type type)
{
if (type == null)
{
throw new ArgumentNullException();
}
if (!typeof(TBase).IsAssignableFrom(type))
{
throw new ArgumentException();
}
return new MyType<TBase> { Value = type };
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
var type = obj as MyType<TBase>;
return type != null && Value.Equals(type.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value.ToString();
}
}
然后:
Dictionary<MyType<MySuperClass>, MySuperClass> dict = new Dictionary<MyType<MySuperClass>, MySuperClass>();
dict.Add(typeof(MyClass1), new MyClass1());
MyType
具有从/到Type
的隐式运算符,因此使用起来非常简单。您只需将Type
强制转换为MyType
(或将MyType
强制转换为Type
),它就可以正常工作。TryGetValue()
:示例
MySuperClass ms;
if (!dict.TryGetValue(typeof(MyClass1), out ms))
{
throw new Exception();
}
请注意,检查是在运行时完成的