具有泛型类型问题的通用方法

时间:2010-10-22 09:09:50

标签: c# generics

我对泛型方法的约束有问题。这是所有类的代码:

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'的隐式引用转换。

如何做到这一点?

1 个答案:

答案 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