Jus*_*gan 56 c# linq language-design
我从这个问题中知道,扩展方法只能在类实例上运行,而不能在静态类本身上运行.这意味着我无法扩展有用的静态类,如Convert
和Math
.
我想知道的是,为什么会这样?从上面的链接,有一些关于C#团队如何实现这种功能的建议.是否有一些哲学上的理由不支持它?
例如,这里有一个理由,为什么没有内置的LINQ ForEach<T>
扩展IEnumerable<T>
.
Eri*_*ert 73
C#团队可以实现这种功能.是否有一些哲学上的理由不支持它?
没有技术原因,也没有哲学原因.然而,正如我经常指出,我没有提供的理由不这样做的特征.功能不便宜; 它们非常昂贵,而且它们不仅要证明自己的成本是合理的,而且必须证明没有完成我们本可以用这个预算完成的其他一百个功能的机会成本.我们必须证明我们的利益相关者的功能成本合理,但我们不需要通过不实现不符合我们标准的功能来节省时间和精力.
特别是,建议的功能对LINQ没有任何作用; 添加了扩展方法以使LINQ工作.任何没有使LINQ工作的东西都很难进入C#3.0; 我们在时间表上做了大量的工作而没有太多的时间去做.(我很惊讶自动属性使它成功.)在设计它之前削减一个不必要的功能节省了大量的时间和精力花在其他事情不要做LINQ的工作.
简而言之:建议的功能从未满足我们的净成本超过成本的标准,我们总是有更多重要的功能来花费我们有限的时间和精力.
Jus*_*gan 13
在阅读了答案以及一些相关问题之后,我在这里总结了对这个问题的理解.
// 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);
Run Code Online (Sandbox Code Playgroud)
该方法实际上不会成为该类的一部分.这就是您无法从扩展方法访问私有成员的原因.扩展方法仅改变C#语法,并且不违反OOP可访问性的概念.实际上,如果你编写一个扩展方法和一个执行相同操作的普通静态方法,那么反编译MSIL,它们完全相同.
因此,如果他们不添加实际功能,为什么要使用扩展方法呢?答案是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);
Run Code Online (Sandbox Code Playgroud)
在某种程度上,所有LINQ都只是语法糖,因为它可以做的一切都可以用一种笨重的非LINQy方式编写.显然,C#团队认为LINQ获得的可读性是值得的,但它引出了一个问题,"为什么他们会停在那里?"
C#编译器开发人员Eric Lippert在博客文章中描述了C#3的很大一部分是创建LINQ所需的所有构造:"隐式类型化本地,匿名类型,lambda表达式,扩展方法,对象和集合初始化器,查询理解,表达式树,[和]改进的方法类型推断." 由于C#团队是2008 .NET版本资源最有限的团队,因此不包括LINQ不是必需的其他类型的扩展.
该团队确实考虑在C#4中实现扩展属性,并且实际上编写了一个工作原型,但是当他们发现它不能使WPF团队实现时(这是该功能的激励因素之一),它被删除了.Eric Lipper后来表示,他们确实考虑过静态类的扩展方法,但无法证明实现,测试和维护成本的真实效益.
可以编写一个接近的扩展方法:
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();
Run Code Online (Sandbox Code Playgroud)
但它非常丑陋.它需要反射,并且不能支持任何类型的智能打字,因为任何人Type
都可以调用它,这可能不是预期的功能.
归档时间: |
|
查看次数: |
9332 次 |
最近记录: |