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

StackOverflow https://stackoverflow.com/questions/31498

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

if (typeof(T) == typeof(String)) return (T)(object)String.Empty;

Другие советы

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

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

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

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

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();
  }
}

Обсуждение 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>();
            } 
        } 

    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top