views:

58

answers:

4

I am writing a class library where i need to extend System.DateTime to have a property called VendorSpecificDay such that

DateTime txnDate = DateTime.Today;

VendorSpecificDayEnum vendorDay = txnDate.VendorSpecificDay;

public enum VendorSpecificDayEnum
{
    Monday, Tuesday, ShoppingDay, HolidayDay
}

I realize that this is a perfect candidate for a System.Core Extension method, but the class library is in .net 2.0 ( i know i am living in dark ages )

Given that Extension methods are syntactical sugar, is there anyway i can achieve this without them ?

Many Thanks

+3  A: 

If you have access to the C# 3.0 compiler in VS 2008, you can use extension methods even if your project targets .NET 2.0. Just define your own ExtensionAttribute:

namespace System.Runtime.CompilerServices
{
    public class ExtensionAttribute : Attribute { }
}

As long as that type exists in a referenced assembly, you can use the this keyword to define extension methods, and can consume them like normal.

dahlbyk
+1  A: 

If you're using .Net 2.0 in Visual Studio 2008 (with the C# 3.0 compiler), you can create your own ExtensionAttribute, like this:

namespace System.Runtime.CompilerServices {
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class |
                    AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute { }
}

After including this attribute, you'll be able to create extension methods in .Net 2.0 projects.


If you're still using VS2005, you're out of luck.

SLaks
+1  A: 

Your sample shows an extension property which (currently) doesn't exist.

"All" extension methods get you is nicer syntax, you can get exactly the same thing with (slightly) uglier code:

static class DateTimeExtensions
{
   static IDictionary<DateTime, VendorSpecificDayEnum> m_VendorSpecificDays = new Dictionary<DateTime, VendorSpecificDayEnum>();
   public static VendorSpecificDayEnum GetVenderSpecificDay(/*this*/ DateTime dt)
   {
      return m_VendorSpecificDays[dt];
   }
}

You would then write

VendorSpecificDayEnum vendorDay = DateTimeExtensions.GetVendorSpecificDay(txnDate);
Dan
+2  A: 

Extension methods are just static methods, that implement "instance methods", by taking a fake "this" pointer:

public static class Extensions
{
    public static int ANewFakeInstanceMethod(this SomeObject instance, string someParam)
    {
        return 0;
    }
}

You can still invoke it just like a static method - this is how the compiler compiles your code, anyhow:

var inst = new SomeObject();
int result1 = inst.ANewFakeInstanceMethod("str");
int result2 = Extensions.ANewFakeInstanceMethod(inst, "str");

If you can't get the extension method syntax, you can still use the 2nd syntax, even if you strip the this from your static method definition:

var inst = new SomeObject();
int result2 = Extensions.ANewFakeInstanceMethod(inst, "str");

public static class Extensions
{
    public static int ANewFakeInstanceMethod(SomeObject instance, string someParam)
    {
        return 0;
    }
}

BUT

The syntax and usage you are trying to implement doesn't make sense. You're taking an existing DateTime object instance (which has its own values for date and time), and trying to implement a new property/method off that instance that will return some unrelated constant.

Just use a static class, and define static read-only properties on it:

public static class KnownDates
{
    public static DateTime StSpruffingsDay
    {
        get
        {
            return new DateTime(1, 2, 3, 4);
        }
    }
}

If this isn't a constant (as in, you need it for the current year), you should add a method that takes a year - not try to jam it into an extension method on top of a DateTime, because DateTime embodies more than just a year.

public static class KnownDates
{
    public static DateTime GetTalkLikeAPirateDay(int year)
    {
        return new DateTime( // Todo: Calculate the value, based on Sept 19th
    }
}

If you really need to get it relative to a DateTime, it still makes your code more clear to pass it to the method:

var fiveMinutesAgo = DateTime.Now.AddMinutes(-5);
// ...
var arrrr = KnownDates.GetTalkLikeAPirateDay(fiveMinutesAgo.Year);

... Than it does to invoke it straight off a DateTime instance:

var fiveMinutesAgo = DateTime.Now.AddMinutes(-5);
// ...
var arrrr = fiveMinutesAgo.GetTalkLikeAPirateDay();
Merlyn Morgan-Graham