[英]Generic method with generic type problem
I have problem with constraints on generic method. 我对通用方法的约束有疑问。 Here is code for all classes:
这是所有类的代码:
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
}
}
}
So, I have main IBusinessObject interface for all business objects (like AccountDetails) and IManager as generic manager interface for business objects. 因此,我具有所有业务对象(例如AccountDetails)的主要IBusinessObject接口,以及IManager作为业务对象的通用管理器接口。 I wanted to create factory for these managers with constraints.
我想为有限制的这些经理创建工厂。 When I try something like this in UnitTest:
当我在UnitTest中尝试这样的事情时:
IManagerFactory factory = new ManagerFactory();
factory.Create<IAccountManager>();
I get error: The type 'Sdk.BusinessLogic.IAccountManager' cannot be used as type parameter 'T' in the generic type or method 'Sdk.BusinessLogic.IManagerFactory.Create()'. 我收到错误消息:类型'Sdk.BusinessLogic.IAccountManager'不能用作通用类型或方法'Sdk.BusinessLogic.IManagerFactory.Create()'中的类型参数'T'。 There is no implicit reference conversion from 'Sdk.BusinessLogic.IAccountManager' to 'Sdk.BusinessLogic.IManager'.
没有从“ Sdk.BusinessLogic.IAccountManager”到“ Sdk.BusinessLogic.IManager”的隐式引用转换。
How can this be done? 如何才能做到这一点?
Basically your problem is that IManager<T>
is invariant, and has to be as you've got values coming out of the API and values going into it. 基本上,您的问题是
IManager<T>
是不变的,并且必须是因为您有从API出来的值和进入其中的值。 So an IAccountManager
isn't an IManager<IBusinessObject>
, because otherwise you could write: 因此,
IAccountManager
不是 IManager<IBusinessObject>
,因为否则您可以编写:
IAccountManager m1 = new SomeImplementation();
IManager<IBusinessObject> m2 = m1;
m2.Add(new SomeArbitraryBusinessObject());
An account manager is only meant to manage accounts , not just any business object. 客户经理仅用于管理帐户 ,而不仅仅是任何业务对象。
One option is to use two generic type parameters instead of one for ManagerFactory.Create
: 一种选择是对
ManagerFactory.Create
使用两个通用类型参数,而不是一个:
public TManager Create<TManager,TObjectType>()
where TManager : IManager<TObjectType>
where TObjectType : IBusinessObject
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.