How do extension methods work under-the-hood?

后端 未结 6 1109
半阙折子戏
半阙折子戏 2021-02-13 12:56

A contractor where I work is using extension methods to implement CRUD on well-known internal classes that we own. I say it is better

相关标签:
6条回答
  • 2021-02-13 13:18

    Under the hood, an extension method is just like a regular method, and the object it's called on is passed as the first parameter (the this parameter). There's nothing special about an extension method, it's just syntax candy.

    It's good practice to avoid extension methods whenever you can. They make the code less readable and less object-oriented.

    If it's a class you own, I see no reason to add an extension method to it.

    0 讨论(0)
  • 2021-02-13 13:19

    Description

    Extension Methods is a language feature. The compiler makes regular IL (aka MSIL or CIL) code from that. No reflection required.

    More Information

    • MSDN - Extension Methods
    • Wikipedia - Common Intermediate Language
    0 讨论(0)
  • 2021-02-13 13:26

    How do extension methods work under-the-hood?

    They're just static methods; the compiler rewrites calls like myObject.MyExtensionMethod() to MyExtensionClass.MyExtensionMethod(myObject).

    Is it better to use inheretance or extension methods on WELL-KNOWN classes that you OWN?

    There's not single answer to this question, it all depends on the context. But usually extension methods are most useful in those cases:

    • you don't own the code for the extended type
    • the method targets an interface and will be the same for all implementations of this interface (e.g. IEnumerable<T> and Linq extension methods)
    0 讨论(0)
  • 2021-02-13 13:33

    In answer to the first question:

    Under the hood, extensions act as Delegates, such that void MyExtension(this object obj) could be rewritten as Action MyDelegate. Where they differ, though, is in syntax when called, as Action must wrap around the object, whereas extensions can be called as if it were a member of the object itself, even though under the hood it is not (nor does it have any direct access to private or protected members of the object, for that matter).

    In answer to the second question:

    I usually reserve extensions for either classes I do not own or Interfaces.

    For example, say you have an interface IAnimal

    Public Interface IAnimal
    {
        void Speak();
        void RunToOwnerWhenCalled();
    }
    

    And the following classes

    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");
        }
    }
    

    Then you could have an extension like

    Public static void CallAnimal(this IAnimal animal)
    {
        animal.RunToOwnerWhenCalled();
    }
    

    And a method like

    Public static void Main
    {
        Cat cat = new Cat();
        cat.CallAnimal();
    }
    

    and the result would show the cat's response "I don't know you" in Console.

    Consider one more class

    Public class Human:Mammal
    {
        Public Human():base()
        {
            Console.WriteLine("To be more specific, I am a human.");
        }
    }
    

    This class wouldn't have the CallAnimal extension, as it does not impliment the IAnimal interface, even though it is a type of Mammal.

    0 讨论(0)
  • 2021-02-13 13:38

    I assume extension methods make heavy use of reflection (which is slower).

    No. Extension methods are resolved at compile-time, no reflection required.
    That negates your performance concerns.

    Is it better to use inheretance or extension methods ?

    I would say neither. Use a Repository (DAL). An entity should be persistence-agnostic (so: no inheritance from a base that does CRUD) and not pretend to be involved where it's not (no extensions).

    You are right that "Using extension methods obfuscates & confuses the source of the CRUD methods" but inheritance is not the solution.

    0 讨论(0)
  • 2021-02-13 13:40

    Your question and the existing answers to it are all missing the bigger picture. New developers joining an on going project should conform to the existing coding styles and standards even if they're not the new persons preferred choices.

    If a change in approach represents a major functional improvement as opposed to a primarily esthetic difference it should still be discussed and approved by the entire team first.

    Once that's done the change should either be mass implemented and the style guide updated to only contain the new approach, or the old approach should be marked as deprecated and modernized as the code containing it is touched. In the latter case it's best to do commit the cleanup changes separately from the addition/removal/modification of existing functionality so that why the individual modifications in the diff were made is kept clear.

    0 讨论(0)
提交回复
热议问题