2008-09-18 75 views
-1

這是不合法的:有沒有一種優雅的方式來實例化具有參數的變量類型?

public class MyBaseClass 
{ 
    public MyBaseClass() {} 
    public MyBaseClass(object arg) {} 
} 


public void ThisIsANoNo<T>() where T : MyBaseClass 
{ 
    T foo = new T("whoops!"); 
} 

爲了做到這一點,你必須做T的類型對象的一些反思或你必須使用Activator.CreateInstance。兩者都非常討厭。有沒有更好的辦法?

回答

1

你不能限制噸至比一個空的構造以外的特殊構造的簽名,但可以約束噸至有一個工廠方法與所需的簽名:

public abstract class MyBaseClass 
{ 
    protected MyBaseClass() {} 
    protected abstract MyBaseClass CreateFromObject(object arg); 
} 

public void ThisWorksButIsntGreat<T>() where T : MyBaseClass, new() 
{ 
    T foo = new T().CreateFromObject("whoopee!") as T; 
} 

然而,我可能會建議在這種情況下使用不同的創建模式,例如Abstract Factory。

0
where T : MyBaseClass, new() 

只適用於無參數公共構造函數。除此之外,回到activator.CreateInstance(這真的不是那麼糟糕)。

+0

不是通用的方式。 – 2008-09-18 20:57:12

2

沒有。如果你沒有傳入參數,那麼你可以限制你的類型參數需要一個無參數的構造函數。但是,如果你需要傳遞參數,那麼你的運氣不好。

-2

我可以看到沒有工作。

但是,阻止你這樣做的原因是什麼?

public void ThisIsANoNo<T>() where T : MyBaseClass 
{ 
    MyBaseClass foo = new MyBaseClass("whoops!"); 
} 

因爲一切都將從MyBaseClass繼承,他們將是MyBaseClass,對吧?

我試了一下,這個工程。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ThisIsANoNo<MyClass>(); 
      ThisIsANoNo<MyBaseClass>(); 
     } 

     public class MyBaseClass 
     { 
      public MyBaseClass() { } 
      public MyBaseClass(object arg) { } 
     } 

     public class MyClass :MyBaseClass 
     { 
      public MyClass() { } 
      public MyClass(object arg, Object arg2) { } 
     } 

     public static void ThisIsANoNo<T>() where T : MyBaseClass 
     { 
      MyBaseClass foo = new MyBaseClass("whoops!"); 
     } 
    } 
} 
+0

如果你有一個只有2個參數的構造函數的派生類,會發生什麼? – 2008-09-18 20:33:56