泛型和反射 - 泛型参数[0] 违反了类型的约束



我已经在这个问题上折腾了一段时间了,本质上我是在尝试实现一个通用的存储库工厂,它被称为:

var resposFactory = new RepositoryFactory<IRepository<Document>>();

存储库工厂如下所示:

public class RepositoryFactory<T> : IRepositoryFactory<T>
{
    public T GetRepository(Guid listGuid,
        IEnumerable<FieldToEntityPropertyMapper> fieldMappings)
    {
        Assembly callingAssembly = Assembly.GetExecutingAssembly();
        Type[] typesInThisAssembly = callingAssembly.GetTypes();
        Type genericBase = typeof (T).GetGenericTypeDefinition();
        Type tempType = (
            from type in typesInThisAssembly
            from intface in type.GetInterfaces()
            where intface.IsGenericType
            where intface.GetGenericTypeDefinition() == genericBase 
            where type.GetConstructor(Type.EmptyTypes) != null
            select type)
            .FirstOrDefault();
        if (tempType != null)
        {
            Type newType = tempType.MakeGenericType(typeof(T));
            ConstructorInfo[] c = newType.GetConstructors();
            return (T)c[0].Invoke(new object[] { listGuid, fieldMappings });
        }
    }
}

当我尝试调用getresponsiory函数时,下面一行失败

Type newType = tempType.MakeGenericType(typeof(T));
我得到的错误是:

ArgumentException - GenericArguments[0], ' framework . repositores . irepository ' 1[Apps.Documents.Entities.]',在'框架。知识库。DocumentLibraryRepository ' 1[T]'违反了类型'T'的约束。

你知道这里出了什么问题吗?

编辑:

存储库的实现如下:

public class DocumentLibraryRepository<T> : IRepository<T>
                                                where T : class, new()
{
   public DocumentLibraryRepository(Guid listGuid, IEnumerable<IFieldToEntityPropertyMapper> fieldMappings)
   {
        ...
   }
   ...
}

和IRepository看起来像:

public interface IRepository<T> where T : class
    {
        void Add(T entity);
        void Remove(T entity);
        void Update(T entity);
        T FindById(int entityId);
        IEnumerable<T> Find(string camlQuery);
        IEnumerable<T> All();
    }

您的代码试图创建DocumentLibraryRepository<IRepository<Document>>的实例而不是DocumentLibraryRepository<Document>

您希望使用以下代码:

var genericArgument = typeof(T).GetGenericArguments().FirstOrDefault();
if (tempType != null && genericArgument != null)
{
    Type newType = tempType.MakeGenericType(genericArgument);

我遇到了完全相同的错误,但问题和解决方案不同。我有4个模型类,1个基类,其中只有3个继承自基类,第4个没有。一旦最后一个类继承了基类,错误就消失了。

这表明您可能对泛型类型DocumentLibraryRepository<T>使用了where约束,并且类型PerpetualDocument与该约束不匹配

也许我的答案可以帮助那些有同样错误的人。我的场景是:

public class B
{
    public string Name;
}
public class A
{
    public EventHandler<B> TypedEvent;
    public void MyMethod(B item)
    {
        if (TypedEvent != null)
        {
            TypedEvent(null, item);
        }
    }
}
public class T
{
    public void Run()
    {
        A item = new A();
        item.TypedEvent += new EventHandler<B>(ItemEvent);
    }
    private void ItemEvent(object sender, B b)
    {
        b.Name = "Loaded";
    }
}

所以在运行时,当Run()方法被加载(未执行),我得到一个异常:

GenericArguments[0]…系统。EventHandler 1 (TEventArgs)违反类型参数"TEventArgs"的约束…on method Run().

我不知道这是否是一个。net错误,但在我的情况下,我解决了这个问题,改变A类的TypedEvent属性的类型从类型的EventHandler<B>EventHandler。我的场景变成:

public class B
{
    public string Name;
}
public class A
{
    public EventHandler TypedEvent;
    public void MyMethod(B item)
    {
        if (TypedEvent != null)
        {
            TypedEvent(item, null);
        }
    }
}
public class T
{
    public void Run()
    {
        A item = new A();
        item.TypedEvent += new EventHandler(ItemEvent);
    }
    private void ItemEvent(object sender, EventArgs e)
    {
        B b = sender as B;
        b.Name = "Loaded";
    }
}

我希望这能帮助到大家。

当我根据Resharper的建议将泛型类型更改为抽象类型时,我遇到了这个问题,显然它无法实例化并导致此错误。

删除了抽象,method.MakeGenericMethod(type)行又可以工作了

相关内容

  • 没有找到相关文章

最新更新