为什么此代码会抱怨“通用类型定义的敏捷性”?
-
04-10-2019 - |
题
我有一个通用类型:
class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>>
以及将(应)为给定词典类型创建此类实例的工厂方法。
private static IEqualityComparer<T> CreateDictionaryComparer<T>()
{
Type def = typeof(DictionaryComparer<,>);
Debug.Assert(typeof(T).IsGenericType);
Debug.Assert(typeof(T).GetGenericArguments().Length == 2);
Type t = def.MakeGenericType(typeof(T).GetGenericArguments());
return (IEqualityComparer<T>)Activator.CreateInstance(t);
}
剥离所有无关的东西 - 即使此代码也会引发相同的例外。
private static object CreateDictionaryComparer()
{
Type def = typeof(DictionaryComparer<,>);
Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });
return Activator.CreateInstance(t);
}
断言通过,所以我知道 T
是通用的,有两个通用论点。与 MakeGenericType
但是,除:
提供的通用参数的数量并不等于通用类型定义的ARITY。
参数名称:实例化
我过去做过这种事情,而我的一生都无法弄清楚为什么在这种情况下这不起作用。 (加上我不得不Google arity).
解决方案
弄清楚了。
我有 DictionaryComparer
被宣布为内部阶级。我只能假设 MakeGenericType
想做一个 Query<T>.DictionaryComparer<string,object>
并且没有提供 T
.
故障代码
class Program
{
static void Main(string[] args)
{
var q = new Query<int>();
q.CreateError();
}
}
public class Query<TSource>
{
public Query()
{
}
public object CreateError()
{
Type def = typeof(DictionaryComparer<,>);
Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });
return Activator.CreateInstance(t);
}
class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>>
{
public DictionaryComparer()
{
}
public bool Equals(IDictionary<TKey, TValue> x, IDictionary<TKey, TValue> y)
{
if (x.Count != y.Count)
return false;
return GetHashCode(x) == GetHashCode(y);
}
public int GetHashCode(IDictionary<TKey, TValue> obj)
{
int hash = 0;
unchecked
{
foreach (KeyValuePair<TKey, TValue> pair in obj)
{
int key = pair.Key.GetHashCode();
int value = pair.Value != null ? pair.Value.GetHashCode() : 0;
hash ^= key ^ value;
}
}
return hash;
}
}
}
其他提示
CLR为应用程序使用的每种类型创建了内部数据结构。这些数据结构称为类型对象。具有通用类型参数的类型称为开放类型, CLR不允许构建任何开放类型的实例 (类似于CLR防止接口类型的实例被构造)。
改变
Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });
在
Type t = def.MakeGenericType(new Type[] { typeof(TSource), typeof(String), typeof(object) });
不隶属于 StackOverflow