实例化和转换扩展通用抽象类的Class

时间:2018-01-06 18:56:59

标签: c# asp.net .net oop generics

我有一个具有泛型

的抽象类
public class ServiceOne : BaseService<DTOParam>
{
public override void Read(DTOParam param)
{
//Do something with this DTOParam
}
}

//Other class
public class ServiceTwo : BaseService<DTOParamtwo>
{
public override void Read(DTOParamtwo param)
{
//Do something with this DTOParamtwo
}
}

我几乎没有其他类扩展这个抽象类

BaseService<T> bs = new ServiceOne();

我一直试图将这些类实例化为

Cannot implicitly convert type ServiceOne to BaseService<T>

抛出错误

{{1}}

如果你删除通用它工作正常,我在这里缺少什么?或者上述方法根本不可能。

4 个答案:

答案 0 :(得分:3)

泛型类是一种语义技巧,当您实例化或创建派生自泛型类时,编译器会为每种类型创建不同的类。因此,没有办法将实现具体类型的派生类转换为无类型基础。

你有两个选择,转换为具体的泛型类型或创建一个底层公共基础(我认为第二个选项是你真正想要的)。要创建一个公共库,在您的实现中,您还可以在基础上创建一个函数,该函数接受一个Object作为参数,该函数将调用真正的通用实现(参见下面的示例)。

投射到具体类型:

BaseService<DTOParam> bs =  new ServiceOne();

建立一个共同基础:

public abstract class BaseService
{
    public abstract void Read(object parm);
}

public abstract class GenericBaseService<T> : BaseService
{
    public override void Read(object parm)
    {
        Read((T)parm);
    }

    public abstract void Read(T parm);
}

public class ServiceOne : GenericBaseService<DTOParam>
{
    public override void Read(DTOParam param)
    {
        //Do something with this DTOParam
    }
}

//Now you can do:
BaseService srv = new ServiceOne();
srv.Read(dataOnject);

答案 1 :(得分:1)

区分大小写可能是一个问题。如果您声明了两个类Baseservice<T>BaseService<T>,那么您可能使用了错误的类型。

问题可能出在包含该语句的方法声明中。

例如,这不起作用:

public static BaseService<T> GetService<T>()
{
    BaseService<T> returnValue = new ServiceOne();
    return returnValue;
}

因为T可以是任何类型,因此您无法将ServiceOne BaseService<DTOParam>分配给BaseService<T>。如果Tint或其他类型,该怎么办?您无法将BaseService<DTOParam>分配给BaseService<ItMightBeAnything>

另一方面,这有效:

public static BaseService<DTOParam> GetService()
{
    BaseService<DTOParam> returnValue = new ServiceOne();
    return returnValue;
} 

答案 2 :(得分:0)

您无法在泛型类型T:

中创建abject和cast
Baseservice bs = new ServiceOne();

应该是:

ServiceOne bs = new ServiceOne();

如果需要,您可以稍后将bs转换为基类,但是您需要和泛型类型:

Baseservice bs1 = (BaseService<DTOParam>)bs;

或者如果你坚持在创建实例上进行强制转换应该是:

Baseservice<DTOParam> bs =  new ServiceOne();

答案 3 :(得分:-2)

您的代码BaseService中的拼写错误应为Baseservice

public class ServiceOne : Baseservice<DTOParam>
{
    public override void Read(DTOParam param)
    {
        //Do something with this DTOParam
    }
}