2010-10-29 6 views
2

Я пишу библиотеку классов, где мне нужно, чтобы продлить System.DateTime иметь свойство VendorSpecificDay таким образом, чтоC# DateTime Добавить свойство без расширения метода

DateTime txnDate = DateTime.Today; 

VendorSpecificDayEnum vendorDay = txnDate.VendorSpecificDay; 

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

Я понимаю, что это идеальный кандидат на метод System.Core Extension, но библиотека классов находится в .net 2.0 (я знаю, что живу в темные времена)

Учитывая, что методы расширения - это синтаксический сахар, добиться этого без них?

Большое спасибо

ответ

2

Если у вас есть доступ к компилятору C# 3.0 в VS 2008, вы можете использовать методы расширения, даже если ваши цели проекта .NET 2.0. Просто определить свои собственный ExtensionAttribute:

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

Пока в ссылочной сборке существует такой типа, вы можете использовать this ключевое слово, чтобы определить методы расширения, и можете потреблять их как обычно.

1

Если вы используете .NET 2.0 в Visual Studio 2008 (с 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

Extension методы - это просто статические методы, которые реализуют «методы экземпляра», используя поддельный «этот» указатель:

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

Если вы не можете получить синтаксис метода расширения, вы можете использовать 2-й синтаксис , даже если вы раздеть 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 a DateTime пример:

var fiveMinutesAgo = DateTime.Now.AddMinutes(-5); 
// ... 
var arrrr = fiveMinutesAgo.GetTalkLikeAPirateDay(); 
Смежные вопросы