我们有一个系统,我们需要动态地改变在一组步骤结束时发生的事情。 我们正在使用代表这样做。但是,我们需要在步骤集的末尾调用的方法具有不同的签名。 我们现在可以选择使用标准委托签名(可能从ASP.Net复制事件处理程序)或者以其他方式执行此操作(不确定!) 有没有办法在.Net 3.5中与代表这样做?或者我们可以使用C#4.0的命名参数或委托上的可选参数吗?
答案 0 :(得分:2)
你的问题非常笼统。但是,我认为您可以使用一些通用委托类型,然后将对最终方法的调用包装成一个简单的lambda表达式,以适当地转换参数。
例如,假设您有一个以两个字符串作为参数触发的事件。这可以使用.NET 3.5中的Action<string, string>
委托创建。然后你将有两个你想要调用的方法(你需要在它们之间动态选择):
void Foo(int n, string s) { /* expects int as the first parameter */ }
void Bar(string concatenated) { /* expects concatenated string */ }
然后你可以像这样创建两个动作委托:
// Converts parameter to int and calls 'Foo'
Action<string, string> callFoo = (s1, s2) => Foo(Int32.Parse(s1), s2);
// Concatenates parameters and calls 'Bar'
Action<string, string> callBar = (s1, s2) => Bar(s1 + ", " + s2);
lambda表达式中的代码用作简单的适配器,将实际参数转换为方法所期望的参数。现在,您可以动态添加/删除callFoo
和callBar
作为处理程序来处理您要处理的事件。
答案 1 :(得分:0)
对于“普通”方法,您可以传入一个打开的参数数组,例如:
public void Test(params string[] string parameters);
您可以使用Object
的开放数组。我不知道这是否也适用于代表,而且你也失去了类型安全性。
您可以使用每个调用方法的参数创建包含不同属性的“状态对象”,该方法只接受一个参数。
public class StateObject1
{
public string parameter1;
public int parameter2;
}
public class StateObject2
{
public DateTime parameter1;
public DateTime parameter2;
}
public void Handler1(object stateObject)
{
if (!(stateObject is StateObject1))
throw new ArgumentException("Invalid state object type");
...
}
public void Handler2(object stateObject)
{
if (!(stateObject is StateObject2))
throw new ArgumentException("Invalid state object type");
...
}
答案 2 :(得分:0)
我们通过使用事件处理程序方法签名解决了这个问题,即我们的委托期望(object sender,eventargs e),我们构建了一个自定义事件args类。