c # DateTime Добавить свойство без расширения Метод - PullRequest
2 голосов
/ 29 октября 2010

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

DateTime txnDate = DateTime.Today;

VendorSpecificDayEnum vendorDay = txnDate.VendorSpecificDay;

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 29 октября 2010

Методы расширения - это просто статические методы, которые реализуют «методы экземпляра», взяв фальшивый указатель «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);

... Чем он сразу же вызываетсяDateTime экземпляр:

var fiveMinutesAgo = DateTime.Now.AddMinutes(-5);
// ...
var arrrr = fiveMinutesAgo.GetTalkLikeAPirateDay();
2 голосов
/ 29 октября 2010

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

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

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

1 голос
/ 29 октября 2010

В вашем примере показано расширение свойство , которого (в настоящее время) не существует.

«Все» методы расширения дают вам более хороший синтаксис, вы можете получить точно то же самое с (немного) более уродливым кодом:

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);
1 голос
/ 29 октября 2010

Если вы используете .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, вам не повезло.

...