我从this question知é“扩展方法åªèƒ½åœ¨ç±»å®žä¾‹ä¸Šæ“作,而ä¸èƒ½åœ¨é™æ€ç±»æœ¬èº«ä¸Šæ“作。这æ„味ç€æˆ‘æ— æ³•æ‰©å±•æœ‰ç”¨çš„é™æ€ç±»ï¼Œå¦‚Convert
å’ŒMath
。
我想知é“çš„æ˜¯ï¼Œä¸ºä»€ä¹ˆä¼šè¿™æ ·ï¼Ÿä»Žä¸Šé¢çš„链接,有一些关于C#团队如何实现这ç§åŠŸèƒ½çš„建议。是å¦æœ‰ä¸€äº›å“²å¦ä¸Šçš„åŽŸå› å¯¼è‡´å®ƒä¸å—支æŒï¼Ÿ
例如,rationale背åŽä¸ºForEach<T>
没有内置的LINQ IEnumerable<T>
扩展å。{/ p>
ç”案 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,é™æ€æ‰©å±•å¾ˆæœ‰ç”¨ã€‚
é™æ€æ‰©å±•ä»…用于使代ç æ›´å…·å¯è¯»æ€§ã€‚它在è¿è¡Œæ—¶æˆ–编译时没有æ„义。