Перегрузка метода для поддержки ссылочных типов и обнуляемых типов - PullRequest
2 голосов
/ 21 сентября 2009

У меня есть метод расширения, который я бы хотел перегрузить, чтобы он мог обрабатывать как ссылочные типы, так и типы значений, допускающие значения NULL. Однако, когда я пытаюсь сделать это, я получаю «Участник с такой же подписью уже объявлен». Может ли C # не использовать квалификатор where в моих общих методах, чтобы отличать их друг от друга? Очевидный способ сделать эту работу - дать каждому методу отдельное имя, но это не кажется мне очень элегантным решением. Каков наилучший способ сделать эту работу?

Пример:

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

Ответы [ 2 ]

7 голосов
/ 21 сентября 2009

Это работает, если тип свойства 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];
}
2 голосов
/ 21 сентября 2009

Как указывалось @ 280Z28 , в вашем случае вы можете обрабатывать оба случая одним методом. Однако, если вам действительно нужны два метода с одной и той же сигнатурой, но разными внутренними компонентами на основе переданного типа, это невозможно в C #.

Из Различия между шаблонами C ++ и C # Generics в MSDN:

  • C # не поддерживает явную специализацию; то есть пользовательская реализация шаблона для определенного типа.
  • C # не поддерживает частичную специализацию: пользовательская реализация для подмножества аргументов типа.
...