locked
Extension method RRS feed

  • Question

  • I have a few questions about extension method.

    1) Does an extension method always need to have the object type(user-defined type/class type) to be the type of the parameter such as (this object obj)?

    2) When creating an extension method, do we always have to create a static class?

    3) For cascaded method calling such as

    Mytime.AddHours(15).Display()
    
    where Mytime is a reference to an object and AddHours() and Display() are the extension methods.

    I know it works from left to right, so Mytime.AddHours(15) will calls the extension method AddHours and then return an object reference and then the Display extension method is called on the object reference just being return by the AddHours() after acting on Mytime.AddHours(). But the question is whether the Display() method always has to be called on the object returned by AddHours() or can't it just be manipulated by Mytime? That's

    Is Mytime.AddHours(15).Display() = Mytime.AddHours(15), Mytime.Display() or (Mytime.AddHours(15)).Display()? What if AddHours does not return an object, will the compiler generate an error?

    4) If the extension method always has to take an object type as parameter, when we use the fully qualified name such as

    TimeExtension.Display(myTime);
    
    where TimeExtension is the class of the extension method, Display is the extension method and myTime is a reference to the object.

    So when we do something like what just mentioned above (question 4), does the argument of TimeExtension.Display(myTime) always have to be an object? since the extension method is like

    public static Display(this Time myTime)?

    Thursday, September 30, 2010 2:12 AM

Answers

  • 1) When you use an extension method the method will always get a reference to the object the method is being used on. The syntax 'this Type name' tells the compiler that this extension method can only be called on 'Type' references (or references of derived types). 

    If AddHours() returns int, you will need an extension method with a signature public static returntype DisplayTime(this int value), otherwise it won't work and you will get a compiler error.

    2) Yes, you can have any number of extension method overloads accepting different input. 

    3) The argument to an extension method can be any type or variable.  The syntax will always be ExtensionMethod(this ExtensionType name, Type argument)

    An extension method is nothing but a reguler method with fancy syntax to make it appear like it belongs to a Type.  Very useful for adding behaviour to types you don't control yourself.

    These two code samples behave the same way.

     public class Time
     {
      public int Hours { get; set; }
      public Time AddHours(int hours)
      {
       Hours += hours;
       return this;
      }
     }
    
    

     --------------------------------------------------

     public class Time
     {
      public int Hours { get; set; }
     }
    
     public static class ExtensionMethods
     {
      public static Time AddHours(this Time time, int hours)
      {
       time.Hours += hours;
       return time;
      }
     }
    

     

    Both times you can do

    Time newTime = myTime.AddHours(15);


    ---
    Happy Coding!
    Morten Wennevik [C# MVP]

    • Marked as answer by Larcolais Gong Thursday, October 7, 2010 4:37 AM
    Thursday, September 30, 2010 6:23 AM
  • Yes, you can use extension methods with any type.
    • Marked as answer by Larcolais Gong Thursday, October 7, 2010 4:37 AM
    Thursday, September 30, 2010 3:07 PM

All replies

  • Not sure I understand the first question. Yes, you need to have the type, no  it does not need to be object. Here is an example of an extension method from the Enum class.

    public static string GetDescription(this Enum currentEnum) 
    { 
      string description = String.Empty; 
      DescriptionAttribute da ; 
    
      FieldInfo fi = currentEnum.GetType(). 
            GetField(currentEnum.ToString()); 
      da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, 
            typeof(DescriptionAttribute)); 
      if (da != null) 
        description = da.Description; 
      else 
        description = currentEnum.ToString(); 
    
      return description; 
    } 
    

    Yes, the extension method needs to be in a static class.

    If MyTime and Addhour both return something of the same type of object, then an extension method on that time (DateTime?) would work with either MyTime or MyTime.Addhour. If it does not return a valid object, you would most likely get an object variable not set type of error.

    Hope this helps.


    www.insteptech.com ; msmvps.com/blogs/deborahk
    We are volunteers and ask only that if we are able to help you, that you mark our reply as your answer. THANKS!
    Thursday, September 30, 2010 3:09 AM
  • afaik

    1-2: are the syntax, just follow it

    3: it work on an instance of a type/class

    if your addhour return nothing, its a void.

    you want to extend void....? well, try it let us know.

    you can extend your mytime with method AddHoursEx(int1), which include 2 functions.

    4: afaik, you can't extend static method.

    Thursday, September 30, 2010 3:12 AM
  • Here is the full implementation of the two classes.

     

     

    Public class Time
    {
       private in hour;
       private int minute;
       private int second;
    
       public void SetTime(int h, int m, int s)
       {
          hour = h;
          Minute = m;
          Second = s;
       }
    
       public string ToUniversalString()
       {
          return string.Format("{0}, {1}, {2}", hour, minute, 
               second);
       }
    
       public override string Tostring()
       {
          return string.Format({0}, {1}, {2}, ((hour == 0 || 
               hour == 12) ? 12 : hour % 12), minute, second));
       }
    
       public int Hour
       {
          get { return hour;}
          set { hour = value;}
       }
    
       public int Minute
       {
          get { return minute;}
          set { minute = value;}
       }
       
        public int Second
       {
          get { return second;}
          set { second = value;}
       }
    }

     

    class TimeExtensionTest
    {
      static void Main()
      {
        Time myTime = new Time();
        myTime.SetTime(11,12,13);
        
        myTime.DisplayTime();
    
        Time timeAdded = myTime.AddHours(5);
    
        myTime.AddHours(11).DisplayTime();
    
        TimeExtensions.DisplayTime(myTime);
      }
    }
    
    static class TimeExtensions
    {
       public static void DisplayTime(this Time aTime)
       {
         Console.WritLine(aTime.Tostring());
       }
    
       public static Time AddHours(this Time aTime, int hours)
       {
         Time newTime = new Time();
         newTime.Minute = aTime.Minute;
         newTime.Second = aTime.Second;
    
         newTime.Hour = (aTime.Hour + hours) % 24;
    
         return newTime;
       }
    }

     

     

    1) well as you can see, the static Time AddHours(this Time aTime, int hours) method does indeed return an object, so

    myTime.AddHours(11).DisplayTime();

    so myTime.AddHours(11) will receive an object and then the object acts on the DisplayTime() method.
    But what if myTime.AddHours(11) does not receive an object but instead, receive int or even does not receive anything if the static
    Time AddHours() method does return an int or has a return type of void? Will DisplayTime() method still be called on myTime? Or does
    it just not work?

    2)If public static void DisplayTime(this Time aTime), the parameter of which could be any other type rather than a class type Time,
    is it possible to replace it with type int or double?

    3)When the class name is used with the extension method call such as TimeExtensions.DisplayTime(myTime);
    Does the argument of DisplayTime(argument) always have to be an object or object reference or it can be any type or any variable?
    Thursday, September 30, 2010 4:44 AM
  • 1) When you use an extension method the method will always get a reference to the object the method is being used on. The syntax 'this Type name' tells the compiler that this extension method can only be called on 'Type' references (or references of derived types). 

    If AddHours() returns int, you will need an extension method with a signature public static returntype DisplayTime(this int value), otherwise it won't work and you will get a compiler error.

    2) Yes, you can have any number of extension method overloads accepting different input. 

    3) The argument to an extension method can be any type or variable.  The syntax will always be ExtensionMethod(this ExtensionType name, Type argument)

    An extension method is nothing but a reguler method with fancy syntax to make it appear like it belongs to a Type.  Very useful for adding behaviour to types you don't control yourself.

    These two code samples behave the same way.

     public class Time
     {
      public int Hours { get; set; }
      public Time AddHours(int hours)
      {
       Hours += hours;
       return this;
      }
     }
    
    

     --------------------------------------------------

     public class Time
     {
      public int Hours { get; set; }
     }
    
     public static class ExtensionMethods
     {
      public static Time AddHours(this Time time, int hours)
      {
       time.Hours += hours;
       return time;
      }
     }
    

     

    Both times you can do

    Time newTime = myTime.AddHours(15);


    ---
    Happy Coding!
    Morten Wennevik [C# MVP]

    • Marked as answer by Larcolais Gong Thursday, October 7, 2010 4:37 AM
    Thursday, September 30, 2010 6:23 AM
  •  public static Time AddHours(this Time time, int hours)
    
    So is it possible to replace the (this Time time, int hours) to something like public static Time AddHours(this int a, int hours) something as such? Or must the parameter be

    public static Time AddHours(this [object type] [object reference], int hours)?

    Can it be something like

    public static Time AddHours(this int time, int hours)?

     

    This is what I am confused about.

    Thursday, September 30, 2010 1:06 PM
  • Yes, you can use extension methods with any type.
    • Marked as answer by Larcolais Gong Thursday, October 7, 2010 4:37 AM
    Thursday, September 30, 2010 3:07 PM