C#:从System.Type动态解析

C#:从System.Type动态解析,c#,.net,type-conversion,C#,.net,Type Conversion,我有一个类型、一个字符串和一个对象 是否有某种方法可以动态调用该字符串的parse方法或转换该类型 基本上,如何删除此逻辑中的if语句 object value = new object(); String myString = "something"; Type propType = p.PropertyType; if(propType == Type.GetType("DateTime")) { value = DateTime.Parse(myString); } i

我有一个类型、一个字符串和一个对象

是否有某种方法可以动态调用该字符串的parse方法或转换该类型

基本上,如何删除此逻辑中的if语句

object value = new object();    
String myString = "something";
Type propType = p.PropertyType;

if(propType == Type.GetType("DateTime"))
{
    value = DateTime.Parse(myString);
}

if (propType == Type.GetType("int"))
{
    value = int.Parse(myString);
}
再做些像这样的事

object value = new object();
String myString = "something";
Type propType = p.PropertyType;


//this doesn't actually work
value = propType .Parse(myString);  
救命!:

var converter = TypeDescriptor.GetConverter(propType);
var result = converter.ConvertFrom(myString);
所有基本类型(加上可为null的
和许多其他内置类型)都已集成到TypeConverter基础结构中,因此支持“开箱即用”


要将自定义类型集成到
TypeConverter
基础结构中,请使用新的
TypeConverter
实现您自己的并用于修饰要转换的类,这应该适用于所有基本类型,以及实现
IConvertible

public static T ConvertTo<T>(object value)
{
    return (T)Convert.ChangeType(value, typeof(T));
}

从技术上讲,查看字符串并确定它代表的类型是不可能的

因此,对于任何通用方法,您至少需要:

  • 要分析的字符串
  • 用于分析的类型

  • 看看static
    Convert.ChangeType()
    方法。

    这似乎是您想要做的事情(至少如果所涉及的类型是您无法修改源代码的类型)需要C语言中没有的类型#


    如果您需要经常这样做,我会将逻辑封装在一个类或方法中,您可以将“myString”和“propType”传递给该类或方法,它将返回值。在该方法中,您只需执行上面的if链,并在找到匹配的if链时返回值。您仍然需要手动列出所有可能的类型,但只需执行一次。

    取决于您希望完成的任务

    1) 如果您只是试图清理代码,并删除重复的类型检查,那么您要做的就是将检查集中在一个方法comme中

    public static T To<T> (this string stringValue)
    {
        T value = default (T);
    
        if (typeof (T) == typeof (DateTime))
        {
            // insert custom or convention System.DateTime 
            // deserialization here ...
        }
        // ... add other explicit support here
        else
        {
            throw new NotSupportedException (
                string.Format (
                "Cannot convert type [{0}] with value [{1}] to type [{2}]." + 
                " [{2}] is not supported.",
                stringValue.GetType (),
                stringValue,
                typeof (T)));
        }
    
        return value;
    }
    
    它将被用作

    // as part of application innitialization
    IConvert<string> stringConverter = container.Resolve<IConvert<string>> ();
    stringConverter.AddConversion<int> (s => Convert.ToInt32 (s));
    stringConverter.AddConversion<Color> (s => CustomColorParser (s));
    
    ...
    
    // a consumer elsewhere in code, say a Command acting on 
    // string input fields of a form
    // 
    // NOTE: stringConverter could be injected as part of DI
    // framework, or obtained directly from IoC container as above
    int someCount = stringConverter.To<int> (someCountString);
    
    Func<string, Color> ToColor = stringConverter.GetConversion <Color> ();
    IEnumerable<Color> colors = colorStrings.Select (s => ToColor (s));
    
    //作为应用程序初始化的一部分
    IConvert-stringConverter=container.Resolve();
    stringConverter.AddConversion(s=>Convert.ToInt32);
    stringConverter.AddConversion(s=>CustomColorParser);
    ...
    //代码中其他地方的使用者,例如作用于
    //表单的字符串输入字段
    // 
    //注:stringConverter可以作为DI的一部分注入
    //框架,或直接从IoC容器获取,如上所述
    int someCount=stringConverter.To(someCountString);
    Func-ToColor=stringConverter.GetConversion();
    IEnumerable colors=colorString.Select(s=>ToColor(s));
    
    我更喜欢后一种方法,因为它可以让您完全控制转换。如果您使用像Castle Windsor或Unity这样的控制反转[IoC]容器,那么将为您注入此服务。此外,因为它是基于实例的,所以您可以有多个实例,每个实例都有自己的转换规则集-例如,如果您有多个用户控件,每个控件都生成自己的
    DateTime
    或其他复杂的字符串格式


    见鬼,即使您希望为单个目标类型支持多个转换规则,这也是可能的,您只需扩展方法参数来指定哪一个即可。

    我遇到了这个问题,我就是这样解决的:

    value = myString;
    var parse = propType.GetMethod("Parse", new[] { typeof(string) });
    if (parse != null) {
      value = parse.Invoke(null, new object[] { value });
    }
    
    …这对我很有效

    总而言之,您试图在对象类型上找到一个静态的“Parse”方法,该方法只接受一个字符串作为参数。如果您找到这样一个方法,那么使用您试图转换的字符串参数调用它。由于p是我的类型的PropertyInfo,因此我通过将我的实例设置为如下值来结束此方法:

    p.SetValue(instance, value, null);
    

    您没有显示
    p
    是如何定义的,输入错误?至少,您应该使用
    is
    运算符。我已更新了您的问题,以便在不使用反射的情况下正确检查类型。@David Pfeffer,
    is
    运算符应用不正确<在此上下文中,代码>is
    将永远不会返回true[
    propType
    的类型始终为
    type
    ]。您想使用
    propType==typeof(DateTime)
    我有这个类型。我在实例化p的地方留下了代码。但是让我们假设我有它。呵呵,别担心,我发现它是因为我自己已经做了很多次;)本可以将其修改为使用
    typeof
    ,但我的代表花在了一个悬赏问题上:从技术上讲,他并没有试图从字符串推断对象类型。给他对象类型,他想从一个表示[string]转到另一个[well-defined object instance],你会如何用这个属性修饰DateTime,还是默认情况下修饰它?既然你需要修饰要转换的类,这对他尝试为内置类型修饰DateTime的示例不管用吗?哇,酷。不知道
    类型描述符
    。你能详细说明一下它的用途吗?也许可以带我们了解一下框架值类型和复杂自定义类型的具体用法?我很想看看集成inThanks需要做多少工作,我只是删除了很多行,因为我无意中实现了一个大的转换器类,它可以完成您在这里所做的一切。很好!很高兴知道。为了清楚起见,您可以补充说,它适用于简单的框架类型。(请参阅Lazarus注释)。如何从类型propType转换为propType.Parse(myString)?我很想知道这是怎么回事。非常感谢!我在寻找类似的东西,并成功了。
    value = myString;
    var parse = propType.GetMethod("Parse", new[] { typeof(string) });
    if (parse != null) {
      value = parse.Invoke(null, new object[] { value });
    }
    
    p.SetValue(instance, value, null);