为啥这段代码会抱怨“泛型类型定义的多样性”?
Posted
技术标签:
【中文标题】为啥这段代码会抱怨“泛型类型定义的多样性”?【英文标题】:Why would this code complain about "the arity of the generic type definition"?为什么这段代码会抱怨“泛型类型定义的多样性”? 【发布时间】:2010-09-22 02:46:51 【问题描述】:我有一个泛型类型:
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)。
【问题讨论】:
您将T
传递给CreateDictionaryComparer
的内容是什么?我已经尝试通过CreateDictionaryComparer<IDictionary<string, string>>()
,这对我来说很好(使用 Mono C# 编译器版本 1.9.1.0)。
我有 DictionaryComparer 作为一个内部类,它本身就是通用的。认为这是在冲洗作品。
出于好奇,您能否提供完整的(失败的)示例,以便我在编译器上进行尝试?
谢谢!我很感激。
【参考方案1】:
想通了。
我将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;
【讨论】:
出于好奇,您能否提供完整(失败)示例,以便我在编译器上进行尝试? 让我看看我能不能把不相关的东西去掉成一个可编译的例子 谢谢!将DictionaryComparer<TKey, TValue>
移到通用容器类 Query<TSource>
之外可以解决此问题。我进行了实验,您可以嵌套DictionaryComparer<TKey, TValue>
,而不是在另一个泛型类中。还想确保我的编译器和运行时环境的行为与您的相同。
作为进一步的实验,提供三种类型 new Type[] typeof(int), typeof(String), typeof(object) 也可以,满足为包含类创建具体类型的需要(虽然删除内部类是更好的解决方案)
谢谢!这个答案让我很开心,因为我绞尽脑汁想弄清楚这一点【参考方案2】:
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) );
【讨论】:
以上是关于为啥这段代码会抱怨“泛型类型定义的多样性”?的主要内容,如果未能解决你的问题,请参考以下文章