Returning the generic type of a given interface in C #
Suppose I have the following setup.
Interface IDALModel {}
Various classes implement this interface like this ...
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;}
}
in another class, I have a method that should return an instance of the class in a generic way.
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;
}
}
The method Embed
is called from elsewhere as such
DataFieldBuilder<IDALModel> Addresses = test.Embed<TenantModel>(t => t.Addresses);
What I am trying to do in the embed method is to extract the base type AddressModel
from the property TenantModel.Addresses
and instantiateDataFieldBuilder<AddressModel>
It doesn't work on line
DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<type>();
with the message "Unable to implicitly convert the type DataFieldBuilder<AddressModel>
toDataFieldBuilder<IDALModel>
I was hoping that since the IDALModel interface is implemented by AddressModel it will work. Not sure what I'm missing here.
For testing purposes, I even tried to hardcode some examples like
DataFieldBuilder<IDALModel> returnObject = new DataFieldBuilder<AddressModel>();
and this gives the same error as well.
source to share
You want covariance:
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>
{
}
source to share