返回 c# 中给定接口的泛型类型

本文关键字:接口 泛型类型 返回 | 更新日期: 2023-09-27 18:36:21

假设我有以下设置。

Interface IDALModel {}

各种类实现此接口,如下所示...

class AddressModel : IDALModel 
{
    public int AddressId {get;set;}
    public string Address {get;set;}
}
class AccountModel : IDALModel
{
    public int AccountId {get;set;}
    public string Name {get;set;}
}
class TenantModel : IDALModel
{
    public int TenantId {get;set;}
    public KeyedCollection<int, AddressModel> Addresses {get;set;}
}

在另一个类中,我有一个方法,它应该以泛型方式返回一个类的实例。

class SomeClass
{
    internal DataFieldBuilder<IDALModel> Embed<T>(Expression<Func<T, object>> embed, string alias = "")
    {
        PropertyInfo propertyInfo = GetPropertyInfo(embed);
        Type type = propertyInfo.PropertyType.GenericTypeArguments[1];
        DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<type>();
    }
    private PropertyInfo GetPropertyInfo<T>(Expression<Func<T, object>> field)
    {
        PropertyInfo propertyInfo;
        if (field.Body is UnaryExpression)
        {
            propertyInfo = ((MemberExpression)((UnaryExpression)field.Body).Operand).Member as PropertyInfo;
        }
        else
        {
            propertyInfo = ((MemberExpression)field.Body).Member as PropertyInfo;
        }
        return propertyInfo;
    }
}

Embed方法从其他地方调用,如下所示

DataFieldBuilder<IDALModel> Addresses = test.Embed<TenantModel>(t => t.Addresses);

我尝试在嵌入方法中做的是从属性TenantModel.Addresses中提取基础类型AddressModel并创建DataFieldBuilder<AddressModel>的实例

这在行上失败

DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<type>();

消息"无法将类型 DataFieldBuilder<AddressModel> 隐式转换为DataFieldBuilder<IDALModel>

我希望由于接口IDALModel是由AddressModel实现的,因此它可以工作。 不知道我在这里错过了什么。

为了进行测试,我什至尝试对一些示例进行硬编码,例如

DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<AddressModel>();

这也给出了同样的错误。

返回 c# 中给定接口的泛型类型

您可以使用泛型方法定义并对其强制实施接口约束:

class SomeClass
{
    public DataFieldBuilder<T> Embed<T>() where T: IDALModel
    {
        var returnObject = new DataFieldBuilder<T>();
        return returnObject;
    }
}

你想要协方差:

public IDataFieldBuilder<IDALModel> Embed<T>() where T : IDALModel
{
    IDataFieldBuilder<IDALModel> returnObject = (IDataFieldBuilder<IDALModel>)new DataFieldBuilder<T>();
    return returnObject;
}
interface IDALModel {}
class AddressModel : IDALModel 
{
    public int AddressId {get;set;}
    public string Address {get;set;}
}
class AccountModel : IDALModel
{
    public int AccountId {get;set;}
    public string Name {get;set;}
}
class DataFieldBuilder<T> : IDataFieldBuilder<T>
{
}
interface IDataFieldBuilder<out T>
{
}