【问题标题】:Is a blank constructor required for WCF [DataContract] classes? Why?WCF [DataContract] 类是否需要空白构造函数?为什么?
【发布时间】:2017-06-18 00:47:18
【问题描述】:

有人告诉我,包含 getter 和 setter 的可序列化对象需要一个空白构造函数,如下所示:

[DataContract]
public class Item
{
    [DataMember]
    public string description { get; set; }

    public Item() {}

    public Item(string description)
    {
        this.description = description;
    }
}

告诉我的原因是这允许使用 setter 构造对象。但是,我发现 Item 的定义如下:

[DataContract]
public class Item
{
    [DataMember]
    public string description { get; set; }

    public Item(string description)
    {
        this.description = description;
    }
}

当通过 WCF 服务引用作为代理类提供时,无需调用构造函数即可构造:

Item item = new Item {description = "Some description"};

问题:

  1. 我在声明new Item 后写的代码块到底是什么
  2. [DataContract] 类是否需要空白构造函数?如果是这样,这个空白构造函数是做什么的?

我发现如果类不是代理类,我无法在没有构造函数的情况下创建对象。

【问题讨论】:

    标签: c# wcf constructor


    【解决方案1】:

    我写的那段代码到底是什么

    Item item = new Item {description = "Some description"};
    

    相等并编译为:

    Item item = new Item();
    item.description = "Some description";
    

    所以它需要一个无参数的构造函数。如果类没有,但有一个参数化的,你必须使用那个:

    Item item = new Item("Some description");
    

    使用命名参数,它看起来像这样:

    Item item = new Item(description: "Some description");
    

    你仍然可以将它与对象初始化语法结合起来:

    var item = new Item("Some description")
    {
        Foo = "bar"
    };
    

    [DataContract] 类是否需要空白构造函数?

    是的。默认序列化器,DataContractSerializer,doesn't use reflection to instantiate a new instancebut still requires a parameterless constructor

    如果找不到无参数构造函数,则无法实例化对象。嗯,它可以,但它没有。因此,如果您要在服务操作中实际使用这个 Item 类:

    public void SomeOperation(Item item)
    {
    }
    

    然后,一旦您从客户端调用此操作,WCF 将抛出异常,因为序列化程序在 Item 上找不到无参数构造函数。

    【讨论】:

    • 谢谢。我的服务中绝对没有通过服务引用使用的 Item 的无参数构造函数。代理类会自动生成空白构造函数吗?
    • 如果一个类根本不包含构造函数,则会自动生成一个无参数的构造函数(参见:msdn.microsoft.com/en-us/library/aa645608(v=vs.71).aspx)。
    • 那我不知道你在问什么。
    • 因为on the client a class with only the properties is generated,没有构造函数或方法(除非您引用包含数据协定的程序集并选择在生成客户端时重用类型,但这是另一回事)。如果您使用Item 作为服务操作参数(IService1.Foo(Item item)),那么当您调用该操作时,它会在运行时崩溃,因为序列化程序在服务端的Item 上找不到无参数的构造函数。
    • Yes. The serializer uses reflection to instantiate a new instance, and does so using the parameterless constructor. 这不是真的。在 WCF 中,一些黑魔法被用来创建对象的实例。另见stackoverflow.com/questions/1076730/…
    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多