扩展方法是如何在引擎盖下工作的

本文关键字:工作 引擎 方法 扩展 | 更新日期: 2023-09-27 18:19:50

我所在的承包商正在使用extension methods在我们拥有的知名内部类上实现CRUD。我认为使用正常的inheritance比使用extension methods更好,原因如下。

  • 使用扩展方法混淆、隐藏&混淆了CCD_ 5方法的来源
  • 我认为extension methods大量使用reflection(后者较慢)

他的逻辑是,"它是编译的,所以很快。"也许我错了。。。但仅仅因为它是编译的并不意味着它不使用反射,也不意味着它比普通继承更快。

所以我的问题是:

  1. extension methods如何在引擎盖下工作
  2. 在您拥有的WELLKNOWN类上使用inheritanceextension methods更好吗

扩展方法是如何在引擎盖下工作的

扩展方法如何在引擎盖下工作?

它们只是静态方法;编译器重写类似CCD_ 11到CCD_。

在您拥有的WELL-KOWN类上使用固有方法还是扩展方法更好?

这个问题没有单一的答案,这完全取决于上下文。但通常扩展方法在这些情况下最有用:

  • 您没有扩展类型的代码
  • 该方法以接口为目标,并且对于该接口的所有实现都是相同的(例如IEnumerable<T>和Linq扩展方法)

我认为扩展方法会大量使用反射(反射比较慢)。

没有。扩展方法在编译时解决,不需要反射
这消除了您对性能的担忧。

使用固有方法还是扩展方法更好?

我也不会这么说。使用存储库(DAL)。一个实体应该是持久性不可知的(所以:没有从执行CRUD的基础继承),并且不假装参与其中(没有扩展)。

"使用扩展方法会混淆CRUD方法的来源"是对的,但继承不是解决方案。

描述

Extension Methods是一种语言特征。编译器从中生成常规的IL(也称为MSILCIL)代码。无需反射。

更多信息

  • 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参数)传递。扩展方法没有什么特别之处,它只是语法糖果

尽可能避免使用扩展方法是一种很好的做法。它们降低了代码的可读性和面向对象性。

如果它是您自己的类,我认为没有理由为它添加扩展方法。