在“对象”上利用隐式类型转换操作符,是否有比使用原始反射更好的方法?



假设您有一个类Foo:

public class Foo
{
    public static implicit operator Foo(string s) 
    {
        return new Foo();
    }
}

如果您尝试以通常的方式利用此操作符,当然可以:

var s = "foo";
Foo foo = s;

但是如果你有操作数(s)但是你只有作为object:

object s = "foo";
Foo foo = s;

这个失败的原因很明显,因为没有从objectFoo的隐式转换。但是,实例一个string,并且在此场景中确实存在类型转换操作符。对于这个问题,假设所讨论的变量(s)可以是许多类型中的任何一种,这些类型可能定义了类型转换操作符来执行所请求的转换。

如果你愿意,你可以使用反射:

object s = "foo";
var converter = typeof(Foo)
    .GetMethods()
    .Single(x => 
        x.Name == "op_Implicit" && 
        x.ReturnType == typeof(Foo) && 
        x.GetParameters().Single().ParameterType == typeof(string));
Foo foo = (Foo)converter.Invoke(null, new[] { s });

我尝试使用Convert.ChangeType(s, typeof(Foo));,但这不起作用。是否有更好的选择或使用反射是最好的选择?(我不喜欢使用反射,因为标准的原因——它可能不是最大的性能和代码的外观是不合适的。但如果这是最好的选择,那就好了。

我不喜欢使用反射的标准原因——它可能不是最大的性能

所需的信息在运行时之前是不可用的,因此您无法避免在运行时确定该信息。

你可以根据你的使用情况优化你的反射:如果你经常需要完全相同的转换,并且你有很少的类型需要转换,你可以创建一个Dictionary<Type, Func<object, Foo>>。为特定类型创建一次DynamicMethod,创建一个委托,并反复调用它。或者,如果在您的使用模式中设置动态方法所增加的时间多于所节省的时间,则每次都动态地确定该方法。

和代码的外观是不合适的。

那么不要直接使用反射,使用那些已经为你完成繁重工作的库。在这种情况下,您应该能够使用dynamic,它在幕后使用反射。

当然,隐藏反射的库使得优化反射的性能变得困难。您将不得不希望实现者做得足够好。但是你可以测量一下

相关内容

  • 没有找到相关文章