返回通用实例

时间:2016-08-17 20:42:14

标签: c# generics

我有一个带有虚方法的基本服务类,它设置对象的属性并返回该对象 然后我有一个从基本服务派生的服务,并覆盖基本方法。在overriden方法中,派生服务执行base.DowWork()以设置公共属性,然后还设置其他属性 因此,根据文章herehere,我可以使用泛型来完成此操作。

    public interface IResult
    {
    }

    public class BaseResult : IResult
    {
        public string CommonProperties { get; set; }
    }

    public class AdditionalResult : BaseResult
    {
        public string AdditionalProperties { get; set; }
    }

    public interface IService<T> where T : IResult
    {
        T DoWork();
    }

    public class BaseService<T> : IService<T> where T : BaseResult, new()
    {
        public virtual T DoWork()
        {
            var t = new T();

            t.CommonProperties = "Some Value";

            return t;
        }
    }
    public class AdditionalService : BaseService<AdditionalResult>
    {
        public override AdditionalResult DoWork()
        {
            var addtionalResult = base.DoWork();

            addtionalResult.CommonProperties = "Override value that was set by BaseService";
            addtionalResult.AdditionalProperties = "Set additional properties";

            return addtionalResult;
        }
    }

到目前为止一切顺利 现在我想创建一个Factory方法,它将返回基于某种类型的服务实例。应用程序将使用工厂获取服务实例并调用DoWork(),如下所示

class Program
    {
        static void Main()
        {
            var factory = new MyFactory();
            var service = factory.GetService(0);
            var iresult = service.DoWork();

            // do something here with IResult              
        }
    }

以下是工厂方法

public class MyFactory
{
    public IService<IResult> GetService(int someType)
    {
        if (someType == 0)
        {
            return (IService<IResult>)new BaseService<BaseResult>();
        }

        if (someType == 1)
        {
            return (IService<IResult>)new AdditionalService();
        }

        // note I may have more types and services here. But for simplicity  i am using only 2

        throw new NotSupportedException();
    }
}

但是我无法弄清楚这种工厂方法的签名是什么?基于建议here我正在投射服务实例但在执行应用程序时我得到运行时异常

  

无法投射类型的对象   &#39; BaseService 1 [BaseResult]&#39;至   类型&#39; IService 1 [IResult]&#39;

如果我没有在工厂中转换服务实例,那么我会得到编译时错误

  

无法隐式转换类型&#39; BaseService&#39;至   &#39; IService&#39 ;.存在显式转换(你错过了吗?   投?)

1 个答案:

答案 0 :(得分:2)

请参阅问题Understanding Covariant and Contravariant interfaces in C#

您想使用协方差(out关键字)。如果将其添加到IService接口泛型类型,它将按预期工作。

public interface IService<out T> where T : IResult

我知道我不喜欢发布链接,但我不能写更多或更好的内容answered in that question