将委托与params关键字匹配的任何方法?
我试图让做以下的事情:将委托与params关键字匹配的任何方法?
public delegate void SomeMethod(params object[] parameters);
这是我的代表。 而且我有一些方法可以运行这个SomeMethod委托(无论传递什么)并返回执行时间。
public TimeSpan BenchmarkMethod(SomeMethod someMethod, params object[] parameters)
{
DateTime benchmarkStart = DateTime.Now;
someMethod(parameters);
DateTime benchmarkFinish = DateTime.Now;
return benchmarkFinish - benchmarkStart;
}
我也有一些方法:
public abstract void InsertObjects (Company c);
所以,我把它声明:
SomeMethod dlg = new SomeMethod(InsertObjects);
TimeSpan executionTime = BenchmarkMethod(dlg, c);
但它不跑,说没有重载 'InsertObjects' 匹配委托'TestFactory.MeasuringFactory.SomeMethod'。有没有办法做到这一点?或者我应该改变我的所有方法接受参数对象[]作为参数?
严格否,方法签名必须完全由委托指定的签名相匹配(除对于协变匹配)。但是,您可以创建object[]
阵列并输入到Delegate.DynamicInvoke(object[] args)
。
编辑:
如果您有关于方法的信息被调用,您可以使用MethodBase.GetParameters().Length
获取参数的数目,这样你就可以正确地大小非类型化参数数组。
为标杆,不过,我想你最好使用实现必要的标杆OPS一个抽象基类:
abstract class Benchmark
{
TimeSpan Run()
{
Stopwatch swatch = Stopwatch.StartNew();
// Optionally loop this several times and divide elapsed time by loops:
RunMethod();
swatch.Stop();
return swatch.Elapsed;
}
///<summary>Override this method with the code to be benchmarked.</summary>
protected abstract void RunMethod()
{
}
}
虚拟方法调度具有相当的潜伏期代表,并比动态调用好得多。
匹配params
参数是编译器魔术,并没有这样的魔术代表。它将匹配一个方法,该方法在正确的位置有一个兼容类型的数组,但没有别的。
所以,是的,您需要更改所有的方法,或者使用匿名方法的包装,像这样:
SomeMethod dlg = new SomeMethod(delegate(Object[] parameters)
{
InsertObjects((Company)parameters[0]);
};
请问使用params关键字匹配代表是否有任何方法?
第他们仍然要尊重类型的差异。
params仅仅是合成糖,用于说明从那以后,调用站点的所有参数都被认为是该方法中相同数组的一部分。
因此,对于方法定义为:
TimeSpan BenchmarkMethod(SomeMethod someMethod, params Company[] parameters)
你可以这样做:
Company company1 = null;
Company company2 = null;
//In BenchmarkMethod, company1 and company2 are considered to be part of
//parameter 'parameters', an array of Company;
BenchmarkMethod(dlg, company1, company2);
但不是:
Company company1 = null;
object company3 = new Company();
BenchmarkMethod(dlg, company1, company3);
因为,虽然公司3包含公司在运行时,它是稳定的抽象类型是对象。
所以现在我们知道参数只是简单地在一个方法上定义一个数组,它允许您在调用站点使用更方便的语法。
现在,让我们与您的代码不工作,你的真正原因预期:类型方差
你委托的定义是:
public delegate void SomeMethod(params object[] parameters);
和你的目标的方法:
public abstract void InsertObjects (Company c);
当调用de使节:
SomeMethod dlg = new SomeMethod(InsertObjects);
TimeSpan executionTime = BenchmarkMethod(dlg, c);
你essentialy说你可以调用传递一个数组与任何类型的对象,而不是类型公司的目标InsertObjects。
这当然是编译器不允许的。
相反地,如果您反转类型的委托和目标的方法,如:
public delegate void SomeMethod(params Company[] parameters);
public TimeSpan BenchmarkMethod(SomeMethod someMethod, params Company[] parameters) {
DateTime benchmarkStart = DateTime.Now;
someMethod(parameters);
DateTime benchmarkFinish = DateTime.Now;
return benchmarkFinish - benchmarkStart;
}
public void InsertObjects(object c) {
Console.WriteLine(c);
}
然后,它会编译,因为你会被传递客户的阵列,以接受任何一种方法一种物体。
结论: 参数不影响类型变异规则。
谢谢!)对不起,没有标记你的伟大答案。只是忘了它。我已经很久以前使用过这些代码,但只是今天标记它) – 0100110010101 2009-10-06 20:20:09
感谢您接受答案。并非每个人都在意在本网站上回到“堆栈”以跟踪最新的变化。 – 2009-10-09 16:32:02