扩展Convert.ChangeType以根据请求生成用户定义的类型 [英] extending Convert.ChangeType to produce user-defined types on request

查看:55
本文介绍了扩展Convert.ChangeType以根据请求生成用户定义的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上课:

 公共类Foo{公共字符串名称{get;放;}} 

是否可以通过Convert.ChangeType从字符串创建Foo实例:

  Type type = typeof(Foo);对象值=一个";值= System.Convert.ChangeType(值,类型); 

这是第三方API尝试重建对象的方式.有人提到使用隐式运算符是可行的,但据我了解,这将使我执行以下操作,而不是创建对象:

  Foo foo = new Foo(){名称=一个"};字符串fooAsString = foo;//隐式转换-无需强制转换 

是否可以通过这种方式创建对象?另外,如果还有另一种方法,我确实可以更改Convert.ChangeType.

更新:我问的原因是因为它引发了异常:

从'System.String'强制转换为无效"JibbaJabba + Foo".

并添加运算符不能解决问题.

解决方案

根据MSDN文档:

要成功完成转换,请输入必须实现IConvertible接口,因为方法简单将呼叫包装到适当的位置 IConvertible 方法.方法要求将 value 转换为 conversionType 受支持.

查看 IConvertible 界面,它具有 ToType 方法.您可以尝试一下吗?(免责声明:我没有.这只是一个想法.)

编辑:在您的情况下,您似乎想将字符串 转换为code> Foo .由于 string 类型(显然)没有在其 IConvertible 实现中定义对 Foo 的转换,所以我相信您很不走运./p>


更新:我不想建议您总是使用这种方式来解决此类问题,但是...

我查看了反射器.它的长;我不会在这里复制它.但基本上是按照文档中的说明进行操作:只有在以下情况下它才有效:

  • value 参数是实现 IConvertible 的类型的非空实例,或者:
  • value 参数的类型和 conversionType 参数的类型相同(因此: Convert.ChangeType(myFoo,typeof(Foo))也可以,尽管它几乎没有用).

然后,它循环遍历 IConvertible 支持的所有类型(显然不包括任何用户定义的类型),并最终使用 TypeConverter 参数

  • 接受某种类型的参数,该参数实现类似于 IParser< T>
  • 的接口

    无论如何,祝你好运.

    Given the class:

    public class Foo
    {
        public string Name { get; set; }
    }
    

    Is it possible to have a Foo instance created from a string through Convert.ChangeType:

    Type type = typeof(Foo);
    object value = "one";
    
    value = System.Convert.ChangeType(value, type);
    

    This is how a 3rd party API is attempting to rebuild objects. Someone mentioned this is possible with implicit operators, but from my understanding that will let me do the following, not create the object:

    Foo foo = new Foo() { Name = "one" };
    string fooAsString = foo;  // implicit conversion -- no cast needed
    

    Is there a way to create the object this way? Also, I do have the ability to change the Convert.ChangeType if there is another way to do this.

    Update: The reason I am asking is because it throws and exception:

    Invalid cast from 'System.String' to 'JibbaJabba+Foo'.

    and adding the operator did not resolve the issue.

    解决方案

    According to the MSDN documentation:

    For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. The method requires that conversion of value to conversionType be supported.

    Looking at the IConvertible interface, it has a ToType method. You could try that, maybe? (Disclaimer: I haven't. It's just a thought.)

    Edit: In your case, it seems that you want to convert from a string to a Foo. Since the string type (obviously) does not define a conversion to Foo in its IConvertible implementation, I believe you're out of luck.


    Update: I don't want to suggest that this is how you should always approach this sort of problem, but...

    I took a look at the code for Convert.ChangeType in Reflector. It's long; I won't reproduce it here. But basically it's doing as the documentation says: it only works if:

    • The value parameter is a non-null instance of a type that implements IConvertible, or:
    • The type of the value parameter and the conversionType parameter are the same (so: Convert.ChangeType(myFoo, typeof(Foo)) would also work, though it'd be pretty useless).

    Then, it cycles through all the types supported by IConvertible (which obviously does not include any user-defined types) and ultimately uses ToType as a fallback.

    So, we need to look at the string type's implementation of ToType.

    Sadly, it is one unfortunate line:

    return Convert.DefaultToType(this, type, provider);
    

    What does DefaultToType do? Exactly the same thing as ChangeType (minus the ToType fallback, obviously to avoid infinite recursion).

    So this just simply isn't going to work.

    If you're absolutely tied to this 3rd party library that's using Convert.ChangeType behind the scenes, I would recommend contacting the library's developer and asking them to extend their API in some way that will allow you to accomplish what you're trying to accomplish. Some possiblities might be:

    • Accepting an optional Converter<string, T> or Func<string, T> delegate parameter, as suggested by Ben Voigt in a comment.
    • Accepting a TypeConverter parameter
    • Accepting a parameter of some type that implements an interface like IParser<T>

    Anyway, best of luck.

    这篇关于扩展Convert.ChangeType以根据请求生成用户定义的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆