2010-10-29 4 views
2

Je vous écris une bibliothèque de classes où je dois étendre System.DateTime d'avoir une propriété appelée VendorSpecificDay telle queC# DateTime Ajouter la propriété sans extension Méthode

DateTime txnDate = DateTime.Today; 

VendorSpecificDayEnum vendorDay = txnDate.VendorSpecificDay; 

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

Je me rends compte que ce un candidat parfait pour une méthode System.Core Extension, mais la bibliothèque de classe est en .net 2.0 (je sais que je vis dans les âges sombres)

Étant donné que les méthodes d'extension sont syntactiques sucre, y at-il de toute façon ic un réaliser ceci sans eux?

Merci beaucoup

Répondre

2

Si vous avez accès au compilateur C# 3.0 dans VS 2008, vous pouvez utiliser des méthodes d'extension, même si vos objectifs de projet .NET 2.0. Il suffit de définir votre propre ExtensionAttribute:

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

Tant que ce type existe dans un ensemble référencé, vous pouvez utiliser le mot-clé this pour définir les méthodes d'extension, et peut les consommer comme normal.

1

Si vous utilisez .Net 2.0 dans Visual Studio 2008 (avec le compilateur C# 3.0 ), vous pouvez créer votre propre ExtensionAttribute, comme ceci:

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

Après avoir inclus cet attribut, vous Sera capable de créer des méthodes d'extension dans les projets .Net 2.0.


Si vous utilisez encore VS2005, vous n'avez pas de chance.

1

Votre exemple montre une extension propriété qui n'existe pas (actuellement).

"Toutes les" méthodes d'extension que vous obtenez est plus agréable syntaxe, vous pouvez obtenir exactement la même chose avec (un peu) le code plus laid:

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

alors vous écrire

VendorSpecificDayEnum vendorDay = DateTimeExtensions.GetVendorSpecificDay(txnDate); 
2

Extension les méthodes ne sont que des méthodes statiques, qui implémentent des "méthodes d'instance", en prenant un faux pointeur "this":

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

Vous pouvez toujours l'invoquer comme une méthode statique - ce qui est la façon dont le compilateur compile votre code, de toute façon:

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

Si vous ne pouvez pas obtenir la syntaxe de méthode d'extension, vous pouvez toujours utiliser la 2ème syntaxe , même si vous arrachez la this de votre définition de méthode statique:

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

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

MAIS

la syntaxe et l'utilisation que vous essayez de mettre en œuvre ne pas de sens. Vous prenez un objet DateTime existant instance (qui a ses propres valeurs pour la date et l'heure), et en essayant d'implémenter une nouvelle propriété/méthode hors de l'instance qui retournera une constante non apparentée.

Il suffit d'utiliser une classe statique, et définir les propriétés en lecture seule statique sur elle:

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

Si ce n'est pas une constante (comme, vous avez besoin pour l'année en cours), vous devez ajouter une méthode qui prend une année - ne pas essayer de le brouiller dans une méthode d'extension sur un DateTime, car DateTime incarne plus d'un an.

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

Si vous avez vraiment besoin de l'obtenir par rapport à un DateTime, il fait toujours votre code plus clair pour passer à la méthode:

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

... qu'il fait pour l'invoquer directement hors d'une instance DateTime:

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