我工作的承包商正在使用extension methods
在我们拥有的众所周知的内部类上实施CRUD
。我说由于以下原因,最好使用普通inheritance
而不是extension methods
。
CRUD
方法的来源。extension methods
大量使用reflection
(速度较慢)。他的逻辑是,“这是编译的,所以它很快。”也许我错了......但是因为它被编译并不意味着它不使用反射,也不意味着它比正常继承更快。
所以我的问题是:
extension methods
如何在幕后工作?inheritance
或extension methods
会更好吗?答案 0 :(得分:19)
扩展方法如何在引擎盖下工作?
它们只是静态方法;编译器会将myObject.MyExtensionMethod()
之类的调用重写为MyExtensionClass.MyExtensionMethod(myObject)
。
在你所掌握的WELL-KNOWN课程中使用inheretance或extension方法会更好吗?
这个问题没有单一答案,这完全取决于具体情况。但通常扩展方法在这些情况下最有用:
IEnumerable<T>
和Linq扩展方法)答案 1 :(得分:12)
我认为扩展方法大量使用反射(速度较慢)。
没有。扩展方法在编译时解决,不需要反映 这否定了你的表现问题。
使用固有或扩展方法是否更好?
我不会说。使用存储库(DAL)。一个实体应该是持久性不可知的(因此:没有来自执行CRUD的基础的继承)并且不假装涉及它不是(没有扩展)。
你是对的“使用扩展方法混淆和混淆CRUD方法的来源”,但继承不是解决方案。
答案 2 :(得分:2)
Extension Methods
是一种语言功能。编译器从中生成常规IL
(又名MSIL
或CIL
)代码。不需要反思。
答案 3 :(得分:1)
您的问题及其现有答案都缺少更大的图景。加入正在进行的项目的新开发人员应该符合现有的编码风格和标准,即使他们不是新人的首选。
如果方法的变化代表了主要的功能改进,而不是主要的美学差异,那么首先应该由整个团队进行讨论和批准。
一旦完成,更改应该是批量实现的,并且样式指南更新为仅包含新方法,或者旧方法应该被标记为已弃用和现代化,因为触及了包含它的代码。在后一种情况下,最好将清理更改与现有功能的添加/删除/修改分开提交,以便保持差异中各个修改的原因。
答案 4 :(得分:1)
回答第一个问题:
在幕后,扩展充当代理,这样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类型。
答案 5 :(得分:0)
在引擎盖下,扩展方法就像常规方法一样,它被调用的对象作为第一个参数(this
参数)传递。扩展方法没有什么特别之处,它只是语法糖果。
尽可能避免使用扩展方法是一种很好的做法。它们使代码的可读性降低,并且不那么面向对象。
如果它是您拥有的类,我认为没有理由为其添加扩展方法。