假设我有以下设置。
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);
我在embed方法中尝试做的是从属性AddressModel
中提取基础类型TenantModel.Addresses
并创建DataFieldBuilder<AddressModel>
的实例
这行失败
DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<type>();
带有消息&#34;无法将DataFieldBuilder<AddressModel>
隐式转换为DataFieldBuilder<IDALModel>
我希望,因为接口IDALModel是由AddressModel实现的,所以它可以工作。不知道我在这里缺少什么。
为了进行测试,我甚至尝试对一些例子进行硬编码,例如
DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<AddressModel>();
这也会产生同样的错误。
答案 0 :(得分:5)
您可以使用通用方法定义并对其强制实施接口约束:
class SomeClass
{
public DataFieldBuilder<T> Embed<T>() where T: IDALModel
{
var returnObject = new DataFieldBuilder<T>();
return returnObject;
}
}
答案 1 :(得分:0)
你想要协方差:
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>
{
}