对于给定的未知类型值,以下扩展方法尝试查找具有单个参数的构造函数,以便可以使用该值调用构造函数。
private static ConstructorInfo ConstructorThatTakesValue
(this Type thisType, object value)
{
return thisType.GetConstructors().FirstOrDefault(c =>
c.GetParameters().Count() == 1 &&
c.GetParameters().First().ParameterType.IsAssignableFrom(value.GetType()));
}
也就是说,如果是var c = typeof(X).ConstructorThatTakesValue(y)
,那么我们可以通过
x
var x = (X)c.Invoke(new object[] { y });
上面的代码就像一个魅力,但Resharper标记包含IsAssignableFrom
的行并显示“使用方法InstanceOfType
”。它还提供了一个QuickFix,其中字面上只是用IsAssignableFrom
替换IsInstanceOfType
,我的直觉与我想要实现的完全相反:
c.GetParameters().First().ParameterType.IsInstanceOfType(value.GetType()));
更可疑的是,此消息显示为“建议”,而不是警告等。也就是说,Resharper似乎认为改变是一种简单的风格改进。
我也试图理解这两种方法的语义,但我也无法理解MSDN上文档的含义。我的理解是,如果class A : B
,则B.GetType().IsAssignableFrom(A.GetType())
和A.GetType().IsInstanceOfType(B.GetType())
。
答案 0 :(得分:4)
一个使用Types和Other实例,实际上一个调用另一个:
public virtual bool IsInstanceOfType(object o)
{
if (o == null)
{
return false;
}
return this.IsAssignableFrom(o.GetType());
}
答案 1 :(得分:1)
Kevin Cooks的回答很好,但是Resharper的引擎中有一个被忽略的地方:它与Objects and Types没有区别(它将Type实例视为Object)。
在这种情况下,如果您的B参数已经已经一个Type对象,它仍会要求您切换到“ IsInstanceOf”。这是错误的,并且在这种非常有限的情况下会导致错误。
编辑:我仔细检查了我的测试用例,发现情况不再如此。当第二个参数类型确实是Type时,它将正确使用IsAssignableFrom方法而不会发出警告。