2011-12-19 62 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