2011-12-18 100 views
20

如何使用DataContract与继承?下面的代码会工作吗?DataContract和继承?

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public String Description { get; set; } 

} 

[DataContract] 
public class SomeData : ConsoleData 
{ 

    [DataMember] 
    public int Volume { get; set; } 
    ...... 
+0

是的。你想用这两个数据合约做什么? – 2011-12-18 21:58:12

回答

34

是的,这是可行的。

DataContractAttributeInherited设置为false,因此有必要将该属性应用于子类和父类(就像您在问题中所做的那样)。


如果您想使用具有多态性的数据契约,则需要使用 KnownType属性。

例如

[ServiceContract] 
interface MyWcfContract 
{ 
     [OperationContract] 
     HandleData(ConsoleData contractData); 
} 

如果你调用像这样的方法:

SomeData someData = new SomeData { Description = "Test", Volume = 30 }; 
// The method is expecting a ConsoleData instance, 
// I'm passing a SomeData instance instead 
myWcfProxy.HandleData(someData); 

然后在服务端解串器将不知道它是SomeData一个实例,只是ConsoleData实例它期望的。 解决此问题的方法是将SomeData类注册为已知类型的ConsoleData

+0

谢谢,真的帮助和解决我的问题 – javapowered 2011-12-18 23:19:22

+0

@Andrew。很长一段时间我对这些主题很感兴趣。是否可以在'[OperationContract] HandleData(Base base);'中并且从SoapUI发送一些来自'Base'的缓存对象?然后,如果c#将会意识到在'base'上它保存了某个子类的实例 - 因此它也调用适当的方法(多态性等) – 2017-04-06 08:39:00

+0

[KnownType(typeof(SomeData))中存在小的语法错误],谢谢你的帖子。 – Shanjee 2018-01-09 09:33:37

2

你需要,如果你使用的是XmlSerializerFormat您的ServiceContract使用KnownType属性:

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public String Description { get; set; } 
} 

[DataContract, KnownType(typeof(ConsoleData))] 
public class SomeData : ConsoleData 
{ 
    [DataMember] 
    public int Volume { get; set; } 
} 
+0

没有'KnownType',什么都行不通?我试过代码,因为我在描述中写道,它似乎工作 – javapowered 2011-12-18 21:59:30

+1

我质疑这一点。将KnownType(typeof(SomeData))放在基类(ConsoleData)上是有意义的,允许您将子实例传递给期望基实例的方法。但我认为你不需要把它放在子实例上。 – 2011-12-18 22:02:40

+0

@javapowered:如果您决定不使用KnownType属性,请注意,因为有特殊情况需要它。一个这样的例子是,如果您要将SomeData作为另一个DataContract的属性公开。 – 2011-12-18 22:03:29