C#:Superclass在upcast之后仍然有子类信息

时间:2012-08-24 02:44:06

标签: c# inheritance upcasting

我有两种类型:BaseQuestionQuestionQuestion继承了BaseQuestion的一些属性。现在我已经创建了一个Web API来使BaseQuestion可用。 Question数据类型具有我不想提供的其他属性。我有一个检索Question的方法,我的初步计划是隐式地将其上传到BaseQuestion。我认为它会丢失所有我不想访问的额外属性,我可以返回它。 嗯,事实并非如此。这就是我的工作:

Question q = allQuestions[0];
BaseQuestion bq = q;
string type = bq.GetType().ToString();

bq的类型仍然是“问题”。我无法访问BaseQuestion属性,但我仍然可以在调试器中看到它们,它们位于我发送给客户端的JSON输出中。

关于如何“强制”bq为BaseQuestion类型并且没有在子类中定义的任何属性的任何想法?

2 个答案:

答案 0 :(得分:11)

类型转换不会改变对象的性质,它只会改变您对象的视图。当您转换为基类型时,您通过过滤器查看对象,该过滤器只能看到基类型上定义的成员,而不管实际对象中定义的其他内容。

当您从Web服务调用返回一个对象时,它将被序列化并通过网络发回 - 它的所有可序列化成员。

可以用来阻止派生的Question类的成员返回API调用者的一种技术是禁止在Question类中声明的成员的序列化。 .NET中有几个序列化子系统,但是如果你使用XmlSerialization,你将使用[XmlIgnore]属性修饰Question类中声明的成员,以防止它们被XmlSerialization序列化。如果您使用的是其他序列化子系统,则需要在该系统中找出其类似内容。

另一种可能性是为您的Web API服务定义接口合同。您的BaseQuestion和Question类将实现一个或多个合约接口。我相信这会将序列化限制为仅在合约界面中定义的属性,而不管实际对象是什么。

如果所有其他方法都失败了,那么强力解决方案是在temp var中构造BaseQuestion的实例,将相关属性从实际的Question对象复制到temp对象,并返回temp对象。这是粗鲁和粗暴的,必须有一个更好的方法,但它会起作用。

答案 1 :(得分:1)

类型转换只会更改对象的引用类型,而不是对象本身。

.GetType()的实例上调用Question将始终返回Question类型,无论引用它的变量类型如何。

如果您需要基本类型,则需要在类型上调用.BaseType属性。

所以,像这样:

string type = q.GetType().BaseType.ToString();