2011-12-19 63 views
3

這是我需要做的事情來創建我需要的類的靈活邏輯結構。重新分配或替換C中的變量類型

類是這樣的:

public class myclass { 
    public Action myaction; 
    public int actionparams; 
    public string label; 

    public void myactionfunction() { 
    //do void parameter action 
    } 

    public void myactionfunction(int myparam) { 
    //do one parameter action 
    } 

    public void myactionfunction(int myparam, int myparam2) { 
    //do two parameter action 
    } 
} 

嗯,我所面臨的問題是,我將使用這個類,其中「myaction」可以任意要求沒有或多達六個參數。因爲需要爲它支持的每個參數定義'Action',所以我可以定義儘可能多的'myactions',但我不希望這樣做,但這不會很理想,因爲我需要硬連線參數類型。

我希望有一種方法中,我能「簡單」重新分配myaction的類型,所以以某種方式我可以這樣做

myaction.type = Action<string,int,int>; //i know this looks bad, but should give the idea 

我看了一下委託的聲明,但不能如果有方法可以將它們用於我的目的。

謝謝。

+0

將類(對象)的實例總是綁定到一個動作w ith相同的參數? – 2011-12-19 09:18:41

+0

這個班級的不同實例會有不同數量的動作參數 – roamcel 2011-12-19 09:21:43

+0

這不是我正在問的問題... – 2011-12-19 09:23:23

回答

1

不,你不能。你可以,但是,使用捕獲這樣,一切都是Action,即:

public void myactionfunction() { 
    myaction =() => DoSomethingWithoutParameters(); 
} 

public void myactionfunction(int myparam) { 
    myaction =() => DoSomethingWithOneParameter(myparam); 
} 

public void myactionfunction(int myparam, int myparam2) { 
    myaction =() => DoSomethingWithTwoParameters(myparam, myparam2); 
} 

如果這實際上代表了默認值,則使用默認值!

public void SomeMethod(int x = 123, int y = 456) { 
    myaction =() => Foo(x, y); 
} 

可以通過任何的被稱爲:

SomeMethod(); 
SomeMethod(1); 
SomeMethod(1, 2); 
SomeMethod(x: 1); 
SomeMethod(y: 2); 
SomeMethod(x: 1, y: 2); 
SomeMethod(y: 2, x: 1); 
+0

這看起來不錯。從來沒有看到這裏的符號。 「myaction =()」被定義爲「捕獲」? – roamcel 2011-12-19 09:23:06

+0

@roamcel不,那(和'=>'一起是* lambda *的開始;捕獲很簡單:lambda包含一個局部變量或參數(例如,「myparam」被「捕獲」)。順便說一句,它在語義上是相同的(在這種情況下):'myAction = delegate {DoSomethingWithOneParameter(myparam); };' – 2011-12-19 09:25:29

+0

非常有趣,謝謝。我接受這是正確的答案,因爲您已經明確指出變量類型不能被重新分配,並提供了一個信息豐富的解決方法。正如我所看到的那樣, – roamcel 2011-12-19 09:27:59

1

嘗試使用optional參數

public void myactionfunction(int myparam, int myparam2 = 0, int myparam3 = 0) { 
... 
} 


void Test() 
{ 
    myactionfunction(5); // Will call myactionfunction(5, 0, 0) 
    myactionfunction(5, 10) // Will call myactionfunction(5, 10, 0) 
    myactionfunction(1, myparam3: 7) // Will call myactionfunction(1, 0, 7) 
} 
+0

不好的做法,如果後來他需要7,8或更多的參數... – 2011-12-19 09:22:56

+1

只有當參數的類型是已知的,這似乎不是這裏的情況。 – AVee 2011-12-19 09:23:11

+0

這是一個非常有用的例子,儘管不適合我的需要。非常感謝 – roamcel 2011-12-19 09:29:36

2

,你可以這樣做:

public void myactionfunction(params object[] prms) 
{ 
    int[] intArray = (int[])prms; 
    //do what ever you need to do... 
} 

這也讓你通過不同的PARAMS類型對於每個動作:

public void myactionfunction(params object[] prms) 
{ 
    if (myAction == ???) 
    { 
     string param1 = (string)prms[0]; 
     //use string as first param 
    } 
    else 
    { 
     int param1 = (int)prms[0]; 
     //use int as first param. 
    } 
    //do what ever you need to do... 
} 

這可以稱爲lik E本:

myactionfunction(); 
myactionfunction(1); 
//and also 
myactionfunction(1,2,3,4,5,6,7,8,9,10); 
+2

當只使用int參數時,更好地使用'params int [] prms'。 – 2011-12-19 09:28:32

+1

非常好的想法,使用對象和之後做適當的鑄造。這讓我走上了正確的軌道,理想地解決了我的問題。謝謝。 – roamcel 2011-12-19 09:30:21

+0

是的,這取決於他需要什麼。正如我在第二段中寫的那樣,它可以用於這種方式的不同參數。 – 2011-12-19 09:30:48

1

關於改變的動作,你可以使用泛型,但不幸的是你不能定義Action作爲約束...所以它有點開放。然後

public class MyClass<TAction> 
{ 
    public TAction Action{get;set;} 
} 

用法可能是(行動1串& 2 INT PARAM):

var c = new MyClass<Action<string,int,int>>(); 

然後你可以指定一個Action

c.Action = (s,i1,i2) => Console.WriteLine("Params were: {0}, {1},{2}",s,i1,i2); 

活生生的例子:http://rextester.com/DUI63303