Лучший способ проверить, является ли универсальный тип строкой? (С #)

c# generics

82499 просмотра

5 ответа

У меня есть универсальный класс, который должен разрешить любой тип, примитив или иначе. Единственная проблема с этим заключается в использовании default(T). Когда вы вызываете default для типа значения или строки, он инициализирует его разумным значением (например, пустой строкой). Когда вы вызываете default(T)объект, он возвращает ноль. По разным причинам нам нужно убедиться, что если это не примитивный тип, то у нас будет экземпляр по умолчанию типа, а не нуль. Вот попытка 1:

T createDefault()
{
    if(typeof(T).IsValueType)
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance<T>();
    }
}

Проблема - строка не является типом значения, но не имеет конструктора без параметров. Итак, текущее решение:

T createDefault()
{
    if(typeof(T).IsValueType || typeof(T).FullName == "System.String")
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance<T>();
    }
}

Но это похоже на клудж. Есть ли лучший способ обработать строковый регистр?

Автор: Rex M Источник Размещён: 11.11.2019 01:44

Ответы (5)


151 плюса

Решение

Имейте в виду, что по умолчанию (строка) имеет значение null, а не string.Empty. Вы можете хотеть особый случай в своем коде:

if (typeof(T) == typeof(String)) return (T)(object)String.Empty;
Автор: Matt Hamilton Размещён: 28.08.2008 02:08

14 плюса

if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
     return default(T);
}
else
{
     return Activator.CreateInstance<T>();
}

Не проверено, но первое, что пришло в голову.

Автор: FlySwat Размещён: 28.08.2008 02:06

4 плюса

Вы можете использовать перечисление TypeCode . Вызовите метод GetTypeCode для классов, которые реализуют интерфейс IConvertible, чтобы получить код типа для экземпляра этого класса. IConvertible реализуется с помощью логических, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char и String, поэтому вы можете проверить примитивные типы, используя это. Больше информации на " Проверка общего типа ".

Автор: jfs Размещён: 28.08.2008 02:18

2 плюса

Лично мне нравится перегрузка метода:

public static class Extensions { 
  public static String Blank(this String me) {      
    return String.Empty;
  }
  public static T Blank<T>(this T me) {      
    var tot = typeof(T);
    return tot.IsValueType
      ? default(T)
      : (T)Activator.CreateInstance(tot)
      ;
  }
}
class Program {
  static void Main(string[] args) {
    Object o = null;
    String s = null;
    int i = 6;
    Console.WriteLine(o.Blank()); //"System.Object"
    Console.WriteLine(s.Blank()); //""
    Console.WriteLine(i.Blank()); //"0"
    Console.ReadKey();
  }
}
Автор: theoski Размещён: 10.02.2015 03:50

-6 плюса

Обсуждение для String здесь не работает.

Я должен был иметь следующий код для генериков, чтобы он работал -

   private T createDefault()
    { 

        {     
            if(typeof(T).IsValueType)     
            {         
                return default(T);     
            }
            else if (typeof(T).Name == "String")
            {
                return (T)Convert.ChangeType(String.Empty,typeof(T));
            }
            else
            {
                return Activator.CreateInstance<T>();
            } 
        } 

    }
Автор: Anil Размещён: 13.02.2011 12:25
Вопросы из категории :
32x32