鉴于课程:
public class Foo
{
public string Name { get; set; }
}
是否可以通过Convert.ChangeType:
从字符串创建Foo实例Type type = typeof(Foo);
object value = "one";
value = System.Convert.ChangeType(value, type);
这是第三方API尝试重建对象的方式。有人提到这可能是隐式运算符,但从我的理解中,我将执行以下操作,而不是创建对象:
Foo foo = new Foo() { Name = "one" };
string fooAsString = foo; // implicit conversion -- no cast needed
有没有办法以这种方式创建对象?此外,如果有另一种方法,我可以更改Convert.ChangeType。
更新 我问的原因是因为它抛出异常:
从'System.String'转换为无效 'JibbaJabba +富'。
并添加运算符无法解决问题。
答案 0 :(得分:20)
要使转换成功,值 必须实施IConvertible 界面,因为方法简单 打电话给合适的人 IConvertible方法。方法 需要将值转换为 conversionType 受支持。
查看 IConvertible
界面,它有一个ToType
方法。你可以试试吗,也许吧? (免责声明:我没有。这只是一个想法。)
修改:在您的情况下,您似乎希望将从转换为string
转换为 a {{1} }。由于Foo
类型(显然)未在其string
实施中定义转换为Foo
,因此我认为您运气不佳。
更新:我不想建议您应该如何处理此类问题,但是......
我在Reflector中查看了IConvertible
的代码。它的长;我不会在这里重现它。但基本上它正如文档所说的那样:只有只有才能起作用:
Convert.ChangeType
参数是实现value
的类型的非null实例,或者:IConvertible
参数的类型和value
参数是相同的(因此:conversionType
也可以使用,但它很无用。)然后,它会遍历Convert.ChangeType(myFoo, typeof(Foo))
支持的所有类型(显然不包含任何用户定义的类型),并最终使用ToType
作为后备。
因此,我们需要查看IConvertible
类型string
的实现。
可悲的是,这是一个不幸的路线:
ToType
return Convert.DefaultToType(this, type, provider);
做什么?与DefaultToType
完全相同(减去ChangeType
回退,显然是为了避免无限递归)。
所以这只是根本不起作用。
如果您完全依赖于在幕后使用ToType
的第三方库,我建议您联系图书馆的开发人员并要求他们以某种方式扩展他们的API,这样您就可以完成任务'试图完成。一些可能性可能是:
Convert.ChangeType
或Converter<string, T>
委托参数,如Ben Voigt在评论中所建议的那样。TypeConverter
参数Func<string, T>
无论如何,祝你好运。
答案 1 :(得分:5)
由于丹涛已经指出,直接从弦上施放不会起作用。你可以为字符串实现自己的包装并使用它吗?像
这样的东西class MyString: IConvertible {
public string Value { get; set; }
...
object IConvertible.ToType(Type conversionType, IFormatProvider provider) {
if (conversionType == typeof(Foo))
return new Foo { Name = Value };
throw new InvalidCastException();
}
}
...
MyString myString = new MyString{Value="one"};
Foo myFoo = (Foo)Convert.ChangeType(myString, typeof(Foo));
不知道这是否是一个有用的想法,但无论如何..
答案 2 :(得分:1)
隐式运算符在这里不起作用?如果Foo是一个你可以修改的类,那么我过去曾经使用过类似的东西,这也允许你将Foo实例与一个字符串进行比较。
public class Foo
{
public string Name { get; set; }
public static implicit operator Foo(string value)
{
return new Foo { Name = value };
}
}
...
Foo foo = "fooTest";
Console.WriteLine("Foo name: {0}", foo.Name);
...
编辑:如果您必须使用ChangeType,那么据我所知您运气不好。如果您可以修改API以使用TypeConverter,则可以使用以下内容。
...
Type type = typeof(Foo);
object value = "one";
var converter = TypeDescriptor.GetConverter(type);
if (converter.CanConvertFrom(value.GetType()))
{
object newObject = converter.ConvertFrom(value);
Console.WriteLine("Foo value: {0}", newObject.ToString());
}
...
public class FooConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
var name = value as string;
if (name != null)
return new Foo { Name = name };
else
return base.ConvertFrom(context, culture, value);
}
}
[TypeConverter(typeof(FooConverter))]
public class Foo
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
答案 3 :(得分:0)
对象value1 =“one”;
Foo value2 =(Foo) System.Convert.ChangeType(value,typeof(Foo));
编辑:
那么,如果您尝试从字符串创建Foo类型,则可以使用反射:
String controlToCreate = "Foo";
Type typeofControl = Type.GetType(controlToCreate,true);