C#:从System.Type动态解析
我有一个类型、一个字符串和一个对象 是否有某种方法可以动态调用该字符串的parse方法或转换该类型 基本上,如何删除此逻辑中的if语句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
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));
}
从技术上讲,查看字符串并确定它代表的类型是不可能的
因此,对于任何通用方法,您至少需要:
要分析的字符串
用于分析的类型
看看staticConvert.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);