一千萬個為什麽

搜索

Cunc中的C#歧義+擴展方法+ lambdas

我一直試圖通過這篇文章:

http://blogs.msdn。 COM/wesdyer /存檔/ 2008/01/11 /的-奇跡 - 的 - monads.aspx

... And something on page 1 made me uncomfortable. In particular, I was trying to wrap my head around the Compose<>() function, and I wrote an example for myself. Consider the following two Func's:

Func addTenth = x => x + 0.10;
Func toPercentString = x => (x * 100.0).ToString() + "%";

沒問題!很容易理解這兩者的作用。

現在,按照本文中的示例,您可以編寫一個通用擴展方法來組合這些函數,如下所示:

public static class ExtensionMethods
{
 public static Func Compose(
  this Func toPercentString,
  Func addTenth)
 {
  return input => toPercentString(addTenth(input));
 }
}

精細。所以現在你可以說:

string x = toPercentString.Compose(addTenth)(0.4);

你得到字符串“50%”

到現在為止還挺好。

但這裏有些含糊不清的東西。假設你寫了另一個擴展方法,所以現在你有兩個函數:

public static class ExtensionMethods
{
 public static Func Compose(
  this Func toPercentString,
  Func addTenth)
 {
  return input => toPercentString(addTenth(input));
 }

 public static Func Compose(this
  Func toPercentString,
  Func addTenth)
 {
  return input => toPercentString(addTenth(input + 99999));
 }
}

這裏有歧義。這兩個功能不具有重疊簽名嗎?是。這甚至編譯?是。哪一個被稱為?第二個(顯然會給你“錯誤的”結果)被調用。如果您註釋掉任一函數,它仍會編譯,但您會得到不同的結果。

It seems like nitpicking, but there's something that deeply offends my sensibilities here, and I can't put my finger on it. Does it have to do with extension methods? Does it have to do with lambdas? Or does it have to do with how Func<> allows you to parameterize the return type? I'm not sure.

我猜這是在規範的某個地方解決的問題,但我甚至不知道Google會發現什麽。

幫幫我!

最佳答案

這裏沒有任何含糊之處。第二個將在完全匹配時被調用。每當匹配不準確時,您將獲得第一個函數,因為默認情況下它將與其他所有函數完全匹配。

If you create a Func, and another that is Func, call .Compose while explicitly specifying , the compiler has enough information to determine that the second version is going to be an exact match and therefore it is the one used.

但請考慮這個愚蠢的例子:

Func doubleString = s => s + s;
Func dateToString = date => date.ToString();

Func composedFunction = doubleString.Compose(dateToString);
Console.WriteLine(composedFunction(DateTime.Now));

哪個版本被調用?結果是什麽?第一個版本,輸出是作為連接到自身的字符串的日期。

On the other hand, if you had a more realistic example using Func and Func and weren't as explicit with the call to Compose, which version gets called?

Func toPercentString = d => d.ToString("0.0%");
Func addTenth = d => d + 0.1;
Console.WriteLine(toPercentString.Compose(addTenth)(0.8));

第一個,因為編譯器確定它與第二個完全匹配。由於我不是Eric Lippert或Jon Skeet,我甚至都不會嘗試解釋那個綁定。


static void DoSomething(float f, double d) { }
static void DoSomething(double d, float f) { }

...

DoSomething(1, 1);

This is ambiguous (and doesn't compile because of it).

轉載註明原文: Cunc中的C#歧義+擴展方法+ lambdas