c#DateTime添加没有扩展名的属性Method

时间:2010-10-29 02:45:15

标签: c# .net datetime .net-2.0 extension-methods

我正在编写一个类库,我需要扩展System.DateTime以获得一个名为VendorSpecificDay的属性,以便

DateTime txnDate = DateTime.Today;

VendorSpecificDayEnum vendorDay = txnDate.VendorSpecificDay;

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

我意识到这是System.Core扩展方法的完美候选者,但是类库是.net 2.0(我知道我生活在黑暗时代)

鉴于Extension方法是语法糖,无论如何我能在没有它们的情况下实现这个目标吗?

非常感谢

4 个答案:

答案 0 :(得分:2)

如果您可以访问VS 2008中的C#3.0编译器,即使您的项目以.NET 2.0为目标,也可以使用扩展方法。只需定义自己的ExtensionAttribute

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

只要该类型存在于引用的程序集中,您就可以使用this关键字来定义扩展方法,并且可以像平常一样使用它们。

答案 1 :(得分: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;
    }
}

<强> BUT

您尝试实现的语法和用法没有意义。您正在使用现有的DateTime对象实例(其具有自己的日期和时间值),并尝试从该实例那将返回一些不相关的常数。

只需使用静态类,并在其上定义静态只读属性:

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

如果这不是一个常量(例如,你需要它在当前年份),你应该添加一个需要一年的方法 - 而不是试图将它塞进{{1}之上的扩展方法},因为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

答案 2 :(得分: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,那你就不走运了。

答案 3 :(得分: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);