2012-02-20 16 views
1

在C#中,我可以以相當簡潔的方式爲類構造函數傳遞一個委託參數列表?C#以相當簡明的方式爲類構造函數傳遞一個參數列表

我知道這是非常情景化的,可能看起來有點奇怪的要求,也不是工廠模式。如果它有助於將其視爲挑戰。這個問題的正確答案可能是這是不可能的。

Func<MyClassConstructionArgsType, MyClass> make_MyClass = 
    args => {return new MyClass(args);}; 

var n = make_MyClass(comma separated arguments); 

我還需要在那裏沒有的參數是什麼,描述的副本,下面的例子是不是一個解決方案:

Func<int, string, MyClass> make_MyClass = 
    (a, b) => {return new MyClass(a, b);}; 

或者,出於同樣的原因是:

Class Args 
{ 
    ... 
} 

Func<Args, MyClass> make_MyClass = 
    a => {return new MyClass(a);}; 

var n = make_MyClass(Args(args)); 

DITO其中是這種情況:

var n = make_MyClass<MyClass>(comma separated arguments); 

對象[] {逗號分隔參數}方法是很好的,除了可選參數也需要支持。 c# class reference as opposed to instance reference

喬希第一個答案似乎接近,可以在C#:

這個問題是從以下問題Anastasiosyal的回答而創建的。

+2

匿名downvoter請使用意見,答案或編輯第一。 – alan2here 2012-02-20 19:00:32

+0

我做不下來的選票,但是看到[此帖更多信息](http://meta.stackexchange.com/questions/121350/ive-just-been-down-voted-how-should-i-react-對此) – 2012-02-20 19:03:04

+0

你要求的是不是特別清楚。你能舉一個例子說明你會如何運作,也許我們可以從那裏開始?此外,你正試圖解決的根本問題?我認爲這與你最後一個問題中討厭的類嵌套有關。我肯定會回答你給出的後兩個例子之一。他們爲什麼不合適? – 2012-02-20 19:05:42

回答

2

並非沒有某種形式的反思。

你可以創建一個使用激活劑委託:

​​

但是,這是接近你可以使用委託。但是,如果您創建一個靜態輔助可以讓這個更漂亮查看:

public static T BuildType<T>(params Object[] args) { 
    return (T) Activator.CreateInstance(typeof (T), args); 
} 

BuildType<MyClass>("String", 32); 

同樣,沒有反映我不知道你能真正實現你想要的。

+2

我只是添加一條評論,我不確定你從這段代碼中獲得了什麼。顯然你知道在編譯時你想要什麼類型的東西,因此不需要委派這種類型的構造。而且,即使這是在運行時完成的事情,它也代表了不需要的間接級別。只需調用Activator.CreateInstance()並完成它。 – Josh 2012-02-20 19:22:00

+0

+1:好幫手方法,我認爲它與OP所想的一樣(或者你可以用C#實現的內容......)。 – 2012-02-20 19:23:11

+0

而@Josh上面提到,非常接近Activator。的CreateInstance。無論哪種方式你都會失去安全感,這真的很痛苦。我會在心跳中從我的項目中刪除該代碼。 – 2012-02-20 19:27:14

0

我還沒有100%清楚你在這裏尋找什麼,但我會有一個擺動。

我假設你想創建一個委託,調用一個類的構造函數,返回該類的新實例。這樣做的微不足道的方法是:

var makeX = new Func<String, Integer, X>((s,i)=>new X(s,i)); 

// To use it 
var myX = makeX("Foo", 5); 

我不確定爲什麼在您的用例中不能「可接受」。如果你能用這種方法指出具體的技術或語法問題,我會盡力解決它們。

編輯:

假設是可以接受的預定義自己的代表:

delegate X makeX(String s, Integer i); 

那麼你可以做:

var myMakeX = new makeX((s,i)=>new X(s,i)); 

// To use it 
var myX = myMakeX("Foo", 5); 

但我懷疑這是我們所短,你可以得到。現在,如果您事先知道,例如,您希望指定「Foo」作爲s的值的所有時間,那麼您可以創建另一個將其短路的代理(使用名爲currying的技術):

var myCurryMaker = new Func<String, Func<Integer, X>>(s => return new Func<Integer, X>(i => new X(s, i))); 
var myCurriedX = myCurryMaker("Foo"); 

// To use it 
var myX = myCurriedX(5); 
+0

這是「String,Integer」部分,如果這可能與typeof(X).ArgTypes相反,那就不太理想。 – alan2here 2012-02-20 19:17:04

+0

沒有字符串,整數部分你會失去類型安全。我會再添加一個可能的選擇。 – 2012-02-20 19:18:46

+0

所以你*想*失去類型安全? – 2012-02-20 20:05:12

0

如何沿着如下因素路線的東西:

public delegate object VariableParamFactoryFunc(params object[] constructorParams); 

public class Factory 
{ 
    private Dictionary<Type, VariableParamFactoryFunc> _registeredTypes = new Dictionary<Type, VariableParamFactoryFunc>(); 

    public void RegisterType<T>(VariableParamFactoryFunc factoryFunc) 
    { 
     _registeredTypes.Add(typeof(T), factoryFunc); 
    } 

    public T Resolve<T>(params object resolutionParams) 
    { 
     VariableParamFactoryFunc factoryFunc; 
     if (_registeredTypes.TryGetValue(typeof(T), out factoryFunc)) 
     { 
      return (T)factoryFunc(); 
     } 
     else 
     { 
      return default(T); 
     } 
    } 
} 

那麼你就先註冊工廠函數使用它:(EG)

var factory = new Factory() // or you can turn it into a singleton, this is just for demonstration 
factory.Register<IMyInterface>((a, b, c) => new ConcreteImplementation(a, b, c)) 
factory.Register<CustomClass>((a, b) => new CustomClass(a, b)); 

,然後通過實際解決,並消耗這些工廠函數:

IMyInterface myInterface = factory.Resolve<IMyInterface>(1, "string", 2.412); 
CustomClass customClass = factory.Resolve<CustomClass>("param1", 1234); 

這應該允許您靈活地解決構造函數wi TH可變數量的參數,無需支付Activator.CreateInstance或反射的性能損失,但你在類型安全鬆動,因爲所有的參數都將被轉換爲對象,你需要轉換他們回到正確的類型在出廠功能

祝你好運!

+0

在我開始之前,它開始瞭解和實現了很多,它是否可以使用名稱引用的可選參數在參數列表中使用...,name:value,...? – alan2here 2012-02-20 19:55:30

+0

另外,CustomClass是不是像MyType是它?我不需要在所使用的行上引用類型名稱。 – alan2here 2012-02-20 19:57:10

+0

這不適用於命名的可選參數,它還要求您指定要使用它的類型,所以我想這不是您要查找的內容 – Anastasiosyal 2012-02-20 20:02:13

相關問題