我对泛型方法的约束有问题。这是所有类的代码:
namespace Sdk.BusinessObjects
{
public interface IBusinessObject
{
}
}
namespace Sdk.BusinessObjects
{
[DataContract]
public class AccountDetails : IBusinessObject
{
[DataMember]
public virtual Guid AccountId { get; set; }
// More properties...
}
}
namespace Sdk.BusinessLogic
{
public interface IManager<T> where T : IBusinessObject
{
T Add(T businessObject);
void Delete(T businessObject);
IList<T> ListAll();
}
}
namespace Sdk.BusinessLogic
{
public interface IAccountManager : IManager<AccountDetails>
{
void ChangeAccountState(Guid accountId, string state);
}
}
namespace Sdk.BusinessLogic
{
public interface IManagerFactory
{
T Create<T>() where T : IManager<IBusinessObject>;
}
public class ManagerFactory : IManagerFactory
{
public T Create<T>() where T : IManager<IBusinessObject>
{
// resolve with Unity and return
}
}
}
因此,我为所有业务对象(如AccountDetails)和IManager提供了主要的IBusinessObject接口,作为业务对象的通用管理器接口。我想为这些有限制的经理人创建工厂。当我在UnitTest中尝试这样的事情时:
IManagerFactory factory = new ManagerFactory();
factory.Create<IAccountManager>();
我收到错误: 类型'Sdk.BusinessLogic.IAccountManager'不能在泛型类型或方法'Sdk.BusinessLogic.IManagerFactory.Create()'中用作类型参数'T'。没有从'Sdk.BusinessLogic.IAccountManager'到'Sdk.BusinessLogic.IManager'的隐式引用转换。
如何做到这一点?
答案 0 :(得分:1)
基本上你的问题是IManager<T>
是不变的,并且必须是因为你已经从API中获得了值并且值进入了它。因此,IAccountManager
不是 IManager<IBusinessObject>
,因为否则您可以写:
IAccountManager m1 = new SomeImplementation();
IManager<IBusinessObject> m2 = m1;
m2.Add(new SomeArbitraryBusinessObject());
客户经理仅用于管理帐户,而不仅仅是管理任何业务对象。
一种选择是使用两个通用类型参数而不是ManagerFactory.Create
:
public TManager Create<TManager,TObjectType>()
where TManager : IManager<TObjectType>
where TObjectType : IBusinessObject