2009-09-21 6 views
2

J'ai une méthode d'extension que je voudrais surcharger pour pouvoir gérer à la fois les types de référence et les types de valeurs NULL. Quand j'essaye de faire ceci, cependant, je reçois "Le membre avec la même signature est déjà déclaré." Est-ce que C# n'utilise pas le qualificatif where sur mes méthodes génériques pour les distinguer les unes des autres? La façon évidente de faire ce travail est de donner un nom distinct à chaque méthode, mais cela ne me semble pas une solution très élégante. Quelle est la meilleure façon de faire ce travail?Surcharge d'une méthode pour prendre en charge les types de référence et les types nullables

Exemple:

public static T Coalesce<T>(this SqlDataReader reader, string property) where T : class 
{ 
    return reader.IsDBNull(reader.GetOrdinal(property)) 
       ? null 
       : (T) reader[property]; 
} 

public static T? Coalesce<T>(this SqlDataReader reader, string property) where T : struct 
{ 
    return reader.IsDBNull(reader.GetOrdinal(property)) 
       ? null 
       : (T?)reader[property]; 
} 

// Usage 
var id = reader.Coalesce<System.Guid?>("OptionalID"); 

Répondre

7

Cela fonctionne si le type de propriété est SqlDataReader.Item[string]object.

public static T Coalesce<T>(this SqlDataReader reader, string property) 
{ 
    return reader.IsDBNull(reader.GetOrdinal(property)) 
       ? default(T) 
       : (T) reader[property]; 
} 
+0

Parfait! Marquez un pour l'équipe ObviousThingsIMissed. :) –

+0

J'ai effectivement supprimé ce post pour commencer à penser que le casting provoquerait un problème de compilation - mais réalisé un peu plus tard qu'il est couvert tant que le type de propriété Item est object. : o –

2

Comme @280Z28 a souligné, dans votre cas, vous pouvez gérer les deux cas avec une méthode. Cependant, si vous voulez vraiment deux méthodes avec la même signature mais des internes différents basés sur le type transmis, ce n'est pas possible en C#.

De Differences Between C++ Templates and C# Generics sur MSDN:

  • C# ne prend pas en charge la spécialisation explicite; c'est-à-dire, une implémentation personnalisée d'un modèle pour un type spécifique.
  • C# ne supporte pas la spécialisation partielle: une implémentation personnalisée pour un sous-ensemble des arguments de type.
Questions connexes