C#中的变量泛型返回类型

ric*_*lla 20 c# generics

有没有办法让方法从方法中返回许多泛型类型中的任何一个?例如,我有以下内容:

public static T ParseAttributeValue<T>(this XElement element, string attribute)
    {
        if(typeof(T) == typeof(Int32))
        {
            return Int32.Parse(element.Attribute(attribute).Value);
        }

        if(typeof(T) == typeof(Double))
        {
            return Double.Parse(element.Attribute(attribute).Value);
        }

        if(typeof(T) == typeof(String))
        {
            return element.Attribute(attribute).Value;
        }

        if(typeof(T) == typeof(ItemLookupType))
        {
            return Enum.Parse(typeof(T), element.Attribute(attribute).Value);
        }
    }
Run Code Online (Sandbox Code Playgroud)

(这只是一个非常快速的模型,我知道任何生产代码都需要在空检查等方面更加彻底......)

但是编译器不喜欢它,抱怨Int32不能隐式转换为T(它也不能用于强制转换).我能理解.在编译时,它无法知道是什么T,但我事先检查它.无论如何我能做到这一点吗?

Jos*_*hua 21

我以前做过这些类型的泛型方法.获得类型推断的最简单方法是提供通用转换器函数.

public static T ParseAttributeValue<T>
          (this XElement element, string attribute, Func<string, T> converter)
{
  string value = element.Attribute(attribute).Value;
  if (String.IsNullOrWhiteSpace(value)) {
    return default(T);
  }

  return converter(value);
}
Run Code Online (Sandbox Code Playgroud)

您可以像下面这样使用它:

int index = element.ParseAttributeValue("index", Convert.ToInt32);
double price = element.ParseAttributeValue("price", Convert.ToDouble);
Run Code Online (Sandbox Code Playgroud)

您甚至可以提供自己的功能并享受世界上所有的乐趣(甚至返回匿名类型):

ItemLookupType lookupType = element.ParseAttributeValue("lookupType",
  value => Enum.Parse(typeof(ItemLookupType), value));

var item = element.ParseAttributeValue("items",
  value => {
    List<string> items = new List<string>();
    items.AddRange(value.Split(new [] { ',' }));
    return items;
  });
Run Code Online (Sandbox Code Playgroud)


Mon*_*mas 8

.Net已经有一堆很棒的字符串转换例程,你可以使用!A TypeConverter可以为您完成大部分繁重的工作.然后,您不必担心为内置类型提供自己的解析实现.

请注意,TypeConverter如果您需要处理在不同文化中表达的解析值,则可以使用API的语言环境感知版本.

以下代码将使用默认区域性解析值:

using System.ComponentModel;

public static T ParseAttributeValue<T>(this XElement element, string attribute)
{
    var converter = TypeDescriptor.GetConverter(typeof(T));
    if (converter.CanConvertFrom(typeof(string)))
    {
        string value = element.Attribute(attribute).Value;
        return (T)converter.ConvertFromString(value);
    }

    return default(T);
}
Run Code Online (Sandbox Code Playgroud)

这适用于许多内置类型,您可以使用a TypeConverterAttribute来装饰自定义类型,以允许它们也参与类型转换游戏.这意味着将来您将能够解析新类型而无需更改实现ParseAttributeValue.

请参阅:http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx