簡體   English   中英

委托與params關鍵字匹配任何方法?

[英]Will Delegate with params keyword match any method?

我正在努力完成以下事情:

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'。 有沒有辦法做到這一點?或者我應該改變我的所有方法來接受params對象[]作為參數?

嚴格來說,方法簽名必須與委托指定的簽名完全匹配(協變匹配除外)。 但是,您可以創建一個object[]數組並將其提供給Delegate.DynamicInvoke(object[] args)

編輯:

如果您有關於要調用的方法的信息,可以使用MethodBase.GetParameters().Length來獲取參數的數量,這樣您就可以正確調整無類型參數數組的大小。

但是,對於基准測試,我認為您最好使用實現必要的基准測試操作的抽象基類:

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關鍵字匹配任何方法?

不, 他們仍然需要尊重類型差異。

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);

因為,雖然company3在運行時包含公司,但它的靜態類型是對象。

所以現在我們知道params只是在方法上定義一個數組,它允許你在調用站點使用更方便的語法。

現在讓我們繼續說明您的代碼無法按預期工作的真正原因:鍵入方差

您的代理人定義為:


public delegate void SomeMethod(params object[] parameters);

並將方法定位為:


public abstract void InsertObjects (Company c);

調用委托時:


SomeMethod dlg = new SomeMethod(InsertObjects);
TimeSpan executionTime = BenchmarkMethod(dlg, c);

您實際上是在說可以調用InsertObjects向它傳遞一個包含任何類型對象的數組,而不是類型為Company的對象。

當然,編譯器不允許這樣做。

相反,如果您反轉委托的類型和目標方法,例如:


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);
}

然后它將編譯,因為您將把一個Customer數組傳遞給一個接受任何類型對象的方法。

結論: params不影響類型方差規則。

匹配params參數是編譯器魔術,並且代理人不存在這樣的魔法。 它將匹配一個方法,該方法在正確的位置具有兼容類型的數組,但沒有別的。

所以是的,您需要更改所有方法,或者使用匿名方法作為包裝器,如下所示:

SomeMethod dlg = new SomeMethod(delegate(Object[] parameters)
{
    InsertObjects((Company)parameters[0]);
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM