假设您有一个班级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;
由于没有从object
到Foo
的隐式转换,因此失败的原因很明显。但是,实例 是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));
,但这不起作用。 有没有更好的选择或使用反射作为最佳选择?(我不满意使用反射的标准原因 - 它可能不是最大的性能和外观代码是不合时宜的。但如果它是最好的选择,那么很好。)
答案 0 :(得分:2)
由于标准原因我不喜欢使用反射 - 它可能不是最佳效果
在运行时之前,所需的信息根本不可用,因此您无法避免在运行时确定该信息。这意味着反思。
您可以根据使用情况优化您的反射:如果您经常需要完全相同的转化,并且您只有少数需要转化的类型,则可以创建Dictionary<Type, Func<object, Foo>>
。为特定类型创建一次DynamicMethod
,创建一个委托,然后反复调用它。或者,如果动态方法的设置增加了比使用模式中节省的时间,则每次动态确定方法。
并且代码的外观不合时宜。
然后不要直接使用反射,使用已经为你做繁重工作的库。在这种情况下,您应该能够使用dynamic
,它在幕后使用反射。
当然,隐藏反射的图书馆很难优化反射的性能。你必须希望实施者做得足够好。但你可以衡量一下。