2010-10-29 66 views
2

我寫一個類庫,我需要延長的System.DateTime有一個叫VendorSpecificDay性能,使得C#的DateTime添加屬性,而不擴展方法

DateTime txnDate = DateTime.Today; 

VendorSpecificDayEnum vendorDay = txnDate.VendorSpecificDay; 

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

我意識到,這是一個System.Core擴展方法的完美候選人,但類庫在.net 2.0(我知道我生活在黑暗時代)

鑑於擴展方法是語法糖,有無論如何ic沒有他們做到這一點?

非常感謝

回答

2

如果你有機會到C#3.0編譯器在VS 2008中,你甚至可以,如果你的項目目標.NET 2.0中使用擴展方法。只需定義自己的ExtensionAttribute

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

只要該類型的引用的程序集存在,你可以使用this關鍵字來定義擴展方法,並且會消耗他們像正常的。

1

如果你在Visual Studio 2008中使用的.Net 2.0(用C#3.0 編譯),你可以創建自己的ExtensionAttribute,像這樣:

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

包括這個屬性之後,你」將能夠在.Net 2.0項目中創建擴展方法。


如果您仍在使用VS2005,那麼您運氣不好。

1

您的示例顯示擴展屬性哪些(當前)不存在。

「全部」擴展方法讓你的更好的語法,就可以得到正是與(略)醜陋的代碼同樣的事情:

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

你可以這樣寫

VendorSpecificDayEnum vendorDay = DateTimeExtensions.GetVendorSpecificDay(txnDate); 
2

擴展方法只是靜態方法,通過取一個假的「this」指針來實現「實例方法」:

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

,您仍然可以調用它就像一個靜態方法 - 這是編譯器如何編譯代碼,總之:

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

如果你不能得到擴展方法的語法,你仍然可以使用第二個語法,即使你從你的靜態方法定義剝離this

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

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

的語法和你試圖實現不使用沒有道理。您正在使用現有的DateTime對象實例(它具有其自己的日期和時間值),並嘗試實現一個新的屬性/方法,該實例將返回一些不相關的常量。

只需使用一個靜態類,並在其上定義靜態只讀屬性:

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

如果這不是一個常數(如,你需要它當年),你應該添加一種需要花費一年的方法 - 不要試圖在DateTime之上將其插入到擴展方法中,因爲DateTime體現的不僅僅是一年。

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

如果你真的需要得到它相對於DateTime,它仍然使你的代碼更清晰的將它傳遞給方法:

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

...比它直接調用它off DateTime實例:

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