为什么ä¸æ”¯æŒC#é™æ€ç±»æ‰©å±•æ–¹æ³•ï¼Ÿ

时间:2011-02-05 19:30:46

标签: c# linq language-design

我从this question知é“扩展方法åªèƒ½åœ¨ç±»å®žä¾‹ä¸Šæ“作,而ä¸èƒ½åœ¨é™æ€ç±»æœ¬èº«ä¸Šæ“作。这æ„味ç€æˆ‘无法扩展有用的é™æ€ç±»ï¼Œå¦‚Convertå’ŒMath。

我想知é“的是,为什么会这样?从上é¢çš„链接,有一些关于C#团队如何实现这ç§åŠŸèƒ½çš„建议。是å¦æœ‰ä¸€äº›å“²å­¦ä¸Šçš„原因导致它ä¸å—支æŒï¼Ÿ

例如,rationale背åŽä¸ºForEach<T>没有内置的LINQ IEnumerable<T>扩展å。{/ p>

6 个答案:

答案 0 :(得分:71)

  

C#团队å¯ä»¥å®žçŽ°è¿™ç§åŠŸèƒ½ã€‚是å¦æœ‰ä¸€äº›å“²å­¦ä¸Šçš„原因导致它ä¸å—支æŒï¼Ÿ

没有技术原因,也没有哲学原因。但是,正如我ç»å¸¸æŒ‡å‡ºçš„那样,我ä¸å¿…为ä¸åšä¸€ä¸ªåŠŸèƒ½æä¾›ç†ç”±ã€‚功能ä¸ä¾¿å®œ;它们éžå¸¸æ˜‚贵,而且它们ä¸ä»…è¦è¯æ˜Žè‡ªå·±çš„æˆæœ¬æ˜¯åˆç†çš„,还必须è¯æ˜Žæ²¡æœ‰å®Œæˆæˆ‘们å¯ä»¥ç”¨è¿™ä¸ªé¢„算完æˆçš„其他一百个功能的机会æˆæœ¬ã€‚我们必须è¯æ˜Žæˆ‘们的利益相关者的功能æˆæœ¬åˆç†ï¼Œä½†æˆ‘们ä¸éœ€è¦é€šè¿‡è€Œä¸æ˜¯å®žçŽ°ä¸ç¬¦åˆæˆ‘们标准的功能æ¥èŠ‚çœæ—¶é—´å’Œç²¾åŠ›ã€‚

特别是,建议的功能对LINQ没有任何作用;添加了扩展方法以使LINQ工作。任何没有使LINQ工作的东西都很难进入C#3.0;我们在时间表上åšäº†å¤§é‡çš„工作而没有太多的时间æ¥å®Œæˆã€‚(我很惊讶自动属性使它æˆåŠŸã€‚)在设计它之å‰å‰Šå‡ä¸å¿…è¦çš„功能节çœäº†å¤§é‡çš„时间和精力花在其他åšçš„事情使LINQ工作。

简而言之:建议的功能从æ¥æ²¡æœ‰è¾¾åˆ°æˆ‘们的净æˆæœ¬è¶…过æˆæœ¬çš„标准,我们总是有更é‡è¦çš„功能æ¥èŠ±è´¹æˆ‘们有é™çš„时间和精力。

答案 1 :(得分:12)

在阅读了答案以åŠä¸€äº›ç›¸å…³é—®é¢˜ä¹‹åŽï¼Œæˆ‘在这里总结了对这个问题的ç†è§£ã€‚

扩展方法如何工作

首先,了解é™æ€æ–¹æ³•çš„extensions are just syntactic sugaréžå¸¸é‡è¦ã€‚

// Say you have an extension method that looks like this:
class Extensions
{
    public static void Extend(this SomeClass foo) {}
}

// Here's how you call it
SomeClass myClass;
myClass.Extend();

// The compiler converts it to this:
Extensions.Extend(myClass);

该方法实际上并ä¸å±žäºŽè¯¥ç±»ã€‚这就是你从扩展方法中can't access private members的原因。扩展方法仅改å˜C#语法,并且ä¸è¿åOOPå¯è®¿é—®æ€§çš„概念。实际上,如果你编写一个扩展方法和一个执行相åŒæ“作的普通é™æ€æ–¹æ³•ï¼Œé‚£ä¹ˆå编译MSIL,它们是exactly the same。

为什么存在扩展方法

因此,如果他们ä¸æ·»åŠ å®žé™…功能,为什么è¦ä½¿ç”¨æ‰©å±•æ–¹æ³•ï¼Ÿç­”案是LINQ:

// LINQ makes this easy to read
array.Where(i => i&1 == 0).Select(i => i*i);

// Without extension methods, we would have to do it like this
Enumerable.Select(Enumerable.Where(array, i => i&1 == 0), i => i*i);

在æŸç§ç¨‹åº¦ä¸Šï¼Œæ‰€æœ‰LINQ都åªæ˜¯è¯­æ³•ç³–,因为它å¯ä»¥åšçš„一切都å¯ä»¥ç”¨ä¸€ç§ç¬¨é‡çš„éžLINQyæ–¹å¼ç¼–写。很显然,C#团队认为LINQ获得的å¯è¯»æ€§æ˜¯å€¼å¾—的,但它引出了一个问题,“为什么他们会åœåœ¨é‚£é‡Œï¼Ÿâ€

为什么ä¸ä½¿ç”¨å…¶ä»–扩展类型?

编译器开å‘人员Eric Lippert在blog post中æ述了C#3的很大一部分正在创建LINQ所需的所有构造:“éšå¼ç±»åž‹çš„本地化,匿å类型,lambda表达å¼ï¼Œæ‰©å±•æ–¹æ³•ï¼Œå¯¹è±¡å’Œé›†åˆåˆå§‹å€¼è®¾å®šé¡¹ï¼ŒæŸ¥è¯¢æŽ¨å¯¼ï¼Œè¡¨è¾¾å¼æ ‘,[å’Œ]改进的方法类型推断。“因为C#团队是2008 .NET版本中资æºæœ€æœ‰é™çš„团队,所以其他类型的ä¸åŒ…括LINQä¸ä¸¥æ ¼å¿…è¦çš„扩展å。

团队确实考虑在C#4中实现扩展属性,并且实际上编写了一个工作原型,但是当他们å‘现它ä¸èƒ½å®žçŽ°WPF团队时(这是该功能的激励因素之一),它被删除了。 Eric LipperåŽæ¥è¡¨ç¤ºä»–们为é™æ€ç±»æ供了did consider扩展方法,但无法è¯æ˜Žå®žçŽ°ï¼Œæµ‹è¯•å’Œç»´æŠ¤æˆæœ¬çš„真实效益。

解决方法

å¯ä»¥ç¼–写一个接近的扩展方法:

public static TResult DoSomething<TType, TResult>(this TType @class)
    {
        // access static methods with System.Reflection
        return default(TResult);
    }

// This works, but poorly
typeof(Math).DoSomething();
typeof(Convert).DoSomething();

但它éžå¸¸éš¾çœ‹ã€‚它需è¦å射,并且ä¸èƒ½æ”¯æŒä»»ä½•ç±»åž‹çš„智能打字,因为任何Type都å¯ä»¥è°ƒç”¨å®ƒï¼Œè€Œè¿™å¯èƒ½ä¸æ˜¯é¢„期的功能。

答案 2 :(得分:3)

扩展方法对对象而ä¸æ˜¯ç±»è¿›è¡Œæ“作。如果你想è¦ä¸€ä¸ªæ‰©å±•æ–¹æ³•æ¥æ“作一个类,我想你å¯ä»¥è¿™æ ·åšï¼š

public static T DoSomething<T>(this T @class) 
    where T:Type
{
    // access static methods via reflection...
    return @class;
}

答案 3 :(得分:3)

我相信你问题的答案是because it doesn't make any sense to extend with static methods。引入Extension methods背åŽçš„主è¦åŽŸå› ä¸æ˜¯æ‚¨ä¸æ‹¥æœ‰çš„extending类。主è¦åŽŸå› æ˜¯å®ƒå…许在这些示例中嵌套reduce方法:

 Enumerable.Select(Enumerable.Where(arr, i => i & 1 == 0), i => i*i); // not the best thing I ever read

 arr.Where(i => i&1 == 0).Select(i => i*i); // wow, I see! These are squares for odd numbers

这就是为什么é™æ€ç±»æ²¡æœ‰extension方法的原因。

答案 4 :(得分:2)

F#中å¯ä»¥è¿›è¡Œé™æ€æ‰©å±•ï¼š

type Platform = 
    | Win32
    | X64
    override this.ToString() = 
        match FSharpValue.GetUnionFields(this, typeof<Platform>) with
        | case, _ -> case.Name.Replace('X', 'x')

type Environment with
    static member Platform =
        if System.IntPtr.Size = 8 then Platform.X64 else Platform.Win32

答案 5 :(得分:1)

那么它ä¸ä»…没有实现,而且会引起方法所属的混淆?引入了é™æ€æ‰©å±•ï¼Œå› ä¸ºlinq出现在更高版本中,并且åªæ˜¯ä»¥æ˜“于编ç çš„æ–¹å¼æ”¯æŒlinq,é™æ€æ‰©å±•å¾ˆæœ‰ç”¨ã€‚

é™æ€æ‰©å±•ä»…用于使代ç æ›´å…·å¯è¯»æ€§ã€‚它在è¿è¡Œæ—¶æˆ–编译时没有æ„义。