2014-02-26 62 views
2

我所編寫的代碼如下傳遞參數到通用類型

public interface IScreenBuilder 
{ 
     void Build<TBusinessLogic, TPresenter, TForm> (ILog logger) 
      where TPresenter : class, new() 
      where TForm : class, new();   
} 

public class ScreenBuilder: IScreenBuilder 
{ 
    private ILog _logger; 
    public void Build<TBusinessLogic, TPresenter, TForm>(ILog logger) 
      where TPresenter : class, new() 
      where TForm : class, new() 
    { 
     _logger = logger; 
     TBusinessLogic businessLogic = new BusinessLogicBuilder().Build<TBusinessLogic>(); 
     TPresenter presenter = new TPresenter(businessLogic); 
       TForm form = new TForm(presenter); 
    } 
} 

的構造我需要將參數傳遞到TPresenter和TForm的。我能做到這一點嗎?如果是的話,該如何實現?

回答

2

簡單的答案是,你不能用通用約束來做到這一點。在C#語言中沒有通用的常量,它表示「類型必須具有帶X類型參數的構造函數」。

這意味着您無法使用new TForm(presenter)創建TForm類的對象。

但是 - 這是個好消息 - 它仍然有可能使用反射來做到:

var type = typeof(TPresenter); 
var constructor = type.GetConstructors() 
         .FirstOrDefault(c => 
          (c.GetParameters().Count() == 1) && 
          (c.GetParameters()[0].ParameterType == typeof(TBusinessLogic))); 

if (constructor == null) 
{ 
    throw new SomeException(); 
} 

TPresenter presenter = (TPresenter)constructor.Invoke(
    new object[]{ businessLogic }); 
0

這裏的問題是new()通用約束只能確保類型具有默認的無參數構造函數。所以你的泛型類型不知道它們支持帶參數的構造函數。

而不是傳入構造函數參數,您可以確保您的類型實現一個接口,允許您調用屬性或方法,例如初始化(xxx),它允許您在構建後傳入初始參數。例如,你可以有一個名爲IInitialisable的參數。然後你對你的類型做出了類型約束。

0

對於TPresenter和TForm的你可以替換其中TPresenter:類,新的()與actulal實現或抽象類其中包含參數化構造函數如下

 public void Build<TBusinessLogic, TPresenter, TForm>(ILog logger) 
     where TPresenter : PresenterClass, new() 
      where TForm : FormClass, new() 
    { 
     _logger = logger; 
     TBusinessLogic businessLogic = new BusinessLogicBuilder().Build<TBusinessLogic>(); 
     TPresenter presenter = new TPresenter(10); 
       TForm form = new TForm(20); 
    } 

    public abstract class PresenterClass 
    { 
     public PresenterClass(int parm) 
     { 
     } 
    } 

    public abstract class FormClass 
    { 
     public FormClass(int parm) 
     { 
     } 
    } 
+0

這不起作用。僅僅因爲基類有一個帶有1個參數的構造函數並不意味着具體的確實會有相同的結果。 – Dirk