扩展方法是如何在引擎盖下工作的
本文关键字:工作 引擎 方法 扩展 | 更新日期: 2023-09-27 18:19:50
我所在的承包商正在使用extension methods
在我们拥有的知名内部类上实现CRUD
。我认为使用正常的inheritance
比使用extension methods
更好,原因如下。
- 使用扩展方法混淆、隐藏&混淆了CCD_ 5方法的来源
- 我认为
extension methods
大量使用reflection
(后者较慢)
他的逻辑是,"它是编译的,所以很快。"也许我错了。。。但仅仅因为它是编译的并不意味着它不使用反射,也不意味着它比普通继承更快。
所以我的问题是:
extension methods
如何在引擎盖下工作- 在您拥有的WELLKNOWN类上使用
inheritance
或extension methods
更好吗
扩展方法如何在引擎盖下工作?
它们只是静态方法;编译器重写类似CCD_ 11到CCD_。
在您拥有的WELL-KOWN类上使用固有方法还是扩展方法更好?
这个问题没有单一的答案,这完全取决于上下文。但通常扩展方法在这些情况下最有用:
- 您没有扩展类型的代码
- 该方法以接口为目标,并且对于该接口的所有实现都是相同的(例如
IEnumerable<T>
和Linq扩展方法)
我认为扩展方法会大量使用反射(反射比较慢)。
没有。扩展方法在编译时解决,不需要反射
这消除了您对性能的担忧。
使用固有方法还是扩展方法更好?
我也不会这么说。使用存储库(DAL)。一个实体应该是持久性不可知的(所以:没有从执行CRUD的基础继承),并且不假装参与其中(没有扩展)。
"使用扩展方法会混淆CRUD方法的来源"是对的,但继承不是解决方案。
描述
Extension Methods
是一种语言特征。编译器从中生成常规的IL
(也称为MSIL
或CIL
)代码。无需反射。
更多信息
- MSDN-扩展方法
- 维基百科-通用中间语言
您的问题和现有的答案都缺少大局。加入正在进行的项目的新开发人员应该遵守现有的编码风格和标准,即使他们不是新人的首选。
如果方法的改变代表了一个主要的功能改进,而不是主要的审美差异,那么仍然应该首先由整个团队进行讨论和批准。
一旦完成,就应该大规模实现更改,并更新样式指南以仅包含新方法,或者旧方法应该标记为不推荐使用,并随着包含它的代码的接触而现代化。在后一种情况下,最好将清除更改与现有功能的添加/删除/修改分开提交,这样就可以清楚地了解为什么要在diff中进行单独的修改。
回答第一个问题:
在后台,扩展充当代理,这样void MyExtension(这个对象obj)就可以重写为Action MyDelegate。然而,它们的不同之处在于调用时的语法,因为Action必须包裹在对象周围,而扩展可以被调用,就好像它是对象本身的成员一样,即使在后台它不是(也没有任何直接访问对象的私有或受保护成员的权限)。
回答第二个问题:
我通常为我不拥有的类或接口保留扩展。
例如,假设您有一个接口IAnimal
Public Interface IAnimal
{
void Speak();
void RunToOwnerWhenCalled();
}
和以下类别
public class Mammal
{
public virtual void AnswerWhatAmI()
{
Console.WriteLine("I'm a mammal");
}
}
public class Dog:Mammal, IAnimal
{
public void Speak()
{
Console.WriteLine("arf");
}
public void RunToOwnerWhenCalled()
{
Console.WriteLine("Comming");
}
}
public class Cat:Mammal, IAnimal
{
public void Speak()
{
Console.WriteLine("meow");
}
public void RunToOwnerWhenCalled()
{
Console.WriteLine("I don't know you");
}
}
然后你可以有一个像这样的扩展
Public static void CallAnimal(this IAnimal animal)
{
animal.RunToOwnerWhenCalled();
}
还有像这样的方法
Public static void Main
{
Cat cat = new Cat();
cat.CallAnimal();
}
结果会在控制台中显示猫的回答"我不认识你"。
再考虑一类
Public class Human:Mammal
{
Public Human():base()
{
Console.WriteLine("To be more specific, I am a human.");
}
}
这个类没有CallAnimal扩展,因为它没有实现IAnimal接口,即使它是Mammal的一种类型。
在后台,扩展方法就像一个常规方法,它调用的对象作为第一个参数(this
参数)传递。扩展方法没有什么特别之处,它只是语法糖果。
尽可能避免使用扩展方法是一种很好的做法。它们降低了代码的可读性和面向对象性。
如果它是您自己的类,我认为没有理由为它添加扩展方法。