C#检查一个对象是否可以转换为另一个对象失败?

5

我正在尝试使用IsAssignableFrom检查一个对象是否可以转换为特定类型。然而,我没有得到预期的结果... 这里有什么我漏掉了吗?

//Works (= casts object)
(SomeDerivedType)factory.GetDerivedObject(); 

//Fails (= returns false)
typeof(SomeDerivedType).IsAssignableFrom(factory.GetDerivedObject().GetType()); 

编辑:

上面的例子似乎有误,不能很好地反映我的问题。

我在代码中有一个DerivedType对象,它被强制转换为BaseType

BaseType someObject = Factory.GetItem(); //Actual type is DerivedType

我还通过反射拥有一个PropertyType

PropertyInfo someProperty = entity.GetType().GetProperties().First()

我想检查someObject是否可分配给(可转换为)somePropertyPropertyType。我该怎么做?


1
你能否创建一个完整的程序来展示这种行为? - Lasse V. Karlsen
1
@LasseV.Karlsen,正如您在我的(现已删除的)答案中指出的那样,IsAssignableFrom需要一个类型而不是一个实例。(MSDN在这方面有点误导人)。从上面的代码中,我们可以看出SomeDerivedType t = factory.GetDerivedObject() as SomeDerivedType;是否有效很有趣。 - Steve
4个回答

7
当你拥有

 class B { }
 class D : B {} 

那么。
typeof(B).IsAssignableFrom(typeof(D))   // true
typeof(D).IsAssignableFrom(typeof(B))   // false

我认为你正在尝试第二个表格,但这并不是完全清晰的。
最简单的解决方法可能是进行测试:
 (factory.GetDerivedObject() as SomeDerivedType) != null

编辑后:

你想知道的不是某个对象是否可以分配给某个属性,而是它是否可以转换类型

基础原理如下:

bool ok = someProperty.PropertyType.IsInstanceOfType(someObject);

但这仅仅处理了继承。

1
但是从逻辑上讲,无论从GetDerivedObject返回什么,它必须是SomeDerivedType或其子类,这意味着你代码中的true行应该匹配他所说的最后一行返回false - Lasse V. Karlsen
@LasseV.Karlsen:好的评论,我可能在这里搞错了变量.. 我只是在为验证编写一个小型控制台应用程序。 - Ropstah
@LasseV.Karlsen 不,我期望GetDerivedObject()返回的是一个(最常见的)基类类型的东西,即DerivedType的祖先。但我们需要一个更完整的问题。 - H H
它不能是DerivedType的祖先,你不能这样做:FileStream s = new Stream();(如果我们暂时忘记Stream是抽象的)。 - Lasse V. Karlsen
我更新了我的问题以反映我的问题... 我确实在这里搞糟了变量吗? - Ropstah
显示剩余5条评论

1

尝试使用

if (factory.GetDerivedObject() is SomeDerivedType)
{
//do
}

或者

var tmp = factory.GetDerivedObject() as SomeDerivedType;
if (tmp != null)
{
//do
}

1

因为我看到你的GetDerivedObject()不是泛型的,而且你必须显式地将其结果转换为SomeDerivedType,所以我假设GetDerivedObject被定义为返回SomeDerivedType的基类类型(在极端情况下,是一个object)。

如果是这样的话,这一行:

typeof(SomeDerivedType).IsAssignableFrom(factory.GetDerivedObject().GetType());

翻译成

typeof(SomeDerivedType).IsAssignableFrom(SomeBaseType);

这通常是错误的,因为您无法将基本类型分配给派生类型(您需要显式转换,这就是您所做的)。


在我的例子中,工厂方法返回一个派生类型。然而,在我更新的问题中,你可以看到对象实际上被转换为基础类型。这会影响IsAssignableFrom方法吗? - Ropstah

0

试试这个。它可能有效。它可能需要一些小的更改才能编译。

TypeBuilder b1 = moduleBuilder.DefineType(factory.GetDerivedObject().GetType().Name, TypeAttributes.Public, typeof(SomeDerivedType));

typeof(SomeDerivedType).IsAssignableFrom(b1))

谢谢您的思考,但我认为问题与其他事情有关,也许是我使用了反射? - Ropstah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接