HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Extension methods for methods and properties that don't use non-public data

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
nonpropertiespublicextensionmethodsthatforandusedata

Problem

Generally speaking, I try and write my classes so they are highly cohesive.

Sometimes I have accessors (this problem isn't limited to accessors) which derive their value from non-public data only, which lowers cohesion. (http://www.ndepend.com/metrics.aspx#LCOM)

Take the following class example:

public class Person
{
    public DateTime Birth { get; set; }
    public DateTime? Death { get; set; }

    public double Age 
    {
        get 
        {
            return (Death ?? DateTime.Now - Birth).TotalDays / 365;
        }
    }
}


Ignoring the probable compile errors and lack of error checking, Age could easily be an extension method GetAge as it doesn't rely on non-public data.

The code would look as follows:

public class Person
{
    public DateTime Birth { get; set; }
    public DateTime? Death { get; set; }
}

public static class PersonExtensions
{
    public static double GetAge(this Person person)
    {
        return (person.Death ?? DateTime.Now - person.Birth).TotalDays / 365;
    }
}


What is a good approach to determine whether something should be an extension method or implemented in the class itself?

Some arguments against doing this that I find extension methods have lower visibility, you have to know the extension exists, while if it was a class property its existence would be obvious.

For languages that don't use extension methods (C++, php, etc.) the extension method could be written as a static method which accepts a Person as it's parameter.

Solution

My personal view is create an extension method if:

  • The class/interface you wish to extend is not created by you.



  • The class/interface is created by you but the behavior of the extension method is only required in an assembly that doesn't contain the class (e.g. class Person is defined in MyApp.dll, but GetAge() is only required in MyApp.UI.exe).



  • The behavior can be defined against a more generic abstraction than the class itself where the implementation is the same but the classes don't share a common base. e.g. create an ILifeSpan interface with DateTime DateOfBirth and DateTime DateOfDeath properties and create the extension method public static double GetAge(this ILifeSpan lifeSpan)



FYI extension methods are just a compiler trick, the generated IL just calls the static method, the this keyword just allows you to write less code in visual studio.

when you call person.GetAge();, it is compiled to PersonExtensions.GetAge(person);

Context

StackExchange Code Review Q#25017, answer score: 11

Revisions (0)

No revisions yet.