繁体   English   中英

如何将子类分配给非泛型类中的泛型字段

[英]How do I assign a child class to a generic field in a non-generic class

在C#中,我试图将私有泛型变量存储在通过泛型方法传入的非泛型类中。 泛型方法应该将子类转换为基类类型。

以下是此问题的示例:

class BaseModel { }
class DerivedModel : BaseModel { }

class Data<T> where T : BaseModel { }

// Class is NOT generic
class DataConsumer
{
    // How do I set this to generic?
    private Data<BaseModel> data;

    public void Set<T>(Data<T> data) where T : BaseModel
    {
        // Compile time error: 
        // Cannot convert source type 'Generic.Data<T> 
        // to target type 'Generic.Data<Generic.BaseModel>'
        this.data = data;
    }
}

那是因为您正在尝试将更多派生类型Data<T>分配给基类型Data<BaseModel> ,这在泛型类中是不允许的。

您有两种选择:

1-使DataConsumer通用:

class DataConsumer<T> where T : BaseModel
{
    private Data<T> data;

    public void Set(Data<T> data)
    {
        this.data = data;
    }
}

2- OR,使用out关键字将Data作为接口而不是类,并将T标记为协变类型:

interface IData<out T> where T : BaseModel { }

class DataConsumer
{
    private IData<BaseModel> data;

    public void Set<T>(IData<T> data) where T : BaseModel
    {
        this.data = data;
    }
}

在此处阅读有关泛型中协方差和逆变的更多信息

this.data的类型为Data<BaseModel>而函数参数data的类型为Data<T : BaseModel>

您的示例首先会破坏泛型的整个目的,但您可以将Set()方法声明为非泛型方法,并强制客户端执行强制转换。

private Data<BaseModel> data;

public void Set(Data<BaseModel> data)
{
  this.data = data;
}

作为旁注,如果你声明所涉及的所有实体都是通用的,那么约束只允许你通过BaseModel的契约来操纵对象,所以我看不出如何需要显式转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM