2012-01-03 81 views
2

我有一个泛型类是这样的:如何强制泛型类使用T构造函数的参数?

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 
    } 
} 

终于从映射UserMapper

public class UserMapper : Mapper<User,UserDataAccess> 
{ 
    // Mapping entity properties with datarows columns 
} 

现在想象一下,我需要发送tranName给定TDataAccessUserMapper。如何在不改变DataAccess类的情况下做到这一点?我无法访问DataAccess的源代码,并且泛型没有实现类型不同的构造函数重载。 我知道我可以在UserDataAccess上拥有一个属性并在需要时填充它,但由于线程安全问题,我无法填充该属性。

User类是一个普通的实体 - 它只有属性。

回答

2

泛型不支持。选项:

  • protected virtual TDataAccess CreateDataAccess()方法,即默认使用new TDataAccess(),但可以通过UserMapper覆盖创建对象时,它喜欢的任何方式;调用CreateDataAccess()代替new TDataAccess()
  • 通在工厂方法作为代表,即Func<TDataAccess> - 这样的呼叫者可以提供() => new DataAccess("foo"),和使用,代替new TDataAccess()
  • 使用基于反射的代码来创建TDataAccess - 要么Activator.CreateInstance (支持参数),或一些涉及元编程(ExpressionILGenerator等)
+0

Activator.CreateInstance工程师。谢谢;) – MDP 2012-01-03 10:07:31

3

如可以通过指定构造参数使用Activator.CreateInstance()方法的过载的情况下:

var dataAccess = Activator.CreateInstance(
          typeof(TDataAccess), 
          new object[] { tranName }); 

MSDN

public static Object CreateInstance(
    Type type, 
    params Object[] args 
) 

使用 最好与指定参数匹配的构造创建指定类型的一个实例。

+0

谢谢sll,这是grate idea;) – MDP 2012-01-03 10:08:23

+0

很高兴听到,不客气 – sll 2012-01-03 16:34:54

相关问题