我有一个通用类型:

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) });
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top