是否有更好的方法来利用“对象”上的隐式类型转换运算符而不是使用原始反射?

时间:2015-09-19 01:53:21

标签: c# reflection type-conversion operator-overloading

假设您有一个班级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));,但这不起作用。 有没有更好的选择或使用反射作为最佳选择?(我不满意使用反射的标准原因 - 它可能不是最大的性能和外观代码是不合时宜的。但如果它是最好的选择,那么很好。)

1 个答案:

答案 0 :(得分:2)

  

由于标准原因我不喜欢使用反射 - 它可能不是最佳效果

在运行时之前,所需的信息根本不可用,因此您无法避免在运行时确定该信息。这意味着反思。

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

  

并且代码的外观不合时宜。

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

当然,隐藏反射的图书馆很难优化反射的性能。你必须希望实施者做得足够好。但你可以衡量一下。