我有一个像这样的Generic类:
public class Mapper<TEntity, TDataAccess>
where TEntity : Common.IEntity
where TDataAccess : DataAccess, new()
{
public TDataAccess DataAccess { get; set; }
public Mapper()
{
DataAccess = new TDataAccess();
}
/*
* ...
* */
}
和数据访问是这样的:
public class DataAccess
{
public DataAccess()
{}
public DataAccess(string tranName)
{}
// CRUD functionality and other data access staff
}
和继承的类表单DataAccess
:
public class UserDataAccess:DataAccess
{
public UserDataAccess():base(string.Empty)
{
}
public UserDataAccess(string tranName):base(tranName)
{
// Something to do with user
}
}
来自Mapper的和最后UserMapper
:
public class UserMapper : Mapper<User,UserDataAccess>
{
// Mapping entity properties with datarows columns
}
现在想象一下,我需要tranName
向TDataAccess
中的UserMapper
发送DataAccess
。如何在不改变DataAccess
类的情况下做到这一点?我无法访问UserDataAccess
的源代码,并且Generics也没有实现类型不同的构造函数重载。
我知道我可以在User
上有一个属性并在需要时填写它,但我不能因为线程安全问题而填写。
{{1}}类是一个普通实体 - 它只有属性。
答案 0 :(得分:3)
作为一种情况,您可以通过指定构造函数参数来使用Activator.CreateInstance()方法的重载:
var dataAccess = Activator.CreateInstance(
typeof(TDataAccess),
new object[] { tranName });
MSDN:
public static Object CreateInstance(
Type type,
params Object[] args
)
使用构造函数创建指定类型的实例 最符合指定的参数。
答案 1 :(得分:2)
泛型不支持这一点。选项:
protected virtual TDataAccess CreateDataAccess()
方法,默认情况下使用new TDataAccess()
,但UserMapper
可以覆盖该方法以任意方式创建对象;致电CreateDataAccess()
而非new TDataAccess()
Func<TDataAccess>
- 因此调用者可以提供() => new DataAccess("foo")
,并使用该代替new TDataAccess()
TDataAccess
- Activator.CreateInstance
(支持参数)或涉及元编程的内容(Expression
,ILGenerator
等)