WCF [DataContract]类是否需要一个空的构造函数?为什么?

5
有人告诉我,对于包含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] 类是否需要一个空白构造函数?如果是这样,这个空白的构造函数是做什么的?

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

1个回答

8
“我正在写的那段代码到底是什么?”
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不使用反射实例化新实例, 但仍需要一个无参数的构造函数

如果找不到无参数的构造函数,则无法实例化对象。当然,它可以,但它不会这样做。因此,如果您真的要在服务操作中使用这个Item类:

public void SomeOperation(Item item)
{
}

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

谢谢。我在我的服务中没有一个无参数的Item构造函数,该服务通过服务引用被调用。代理类是否会自动生成一个空构造函数? - Zach Smith
2
如果一个类根本没有包含构造函数,那么一个无参构造函数将自动生成(请参阅:https://msdn.microsoft.com/en-us/library/aa645608(v=vs.71).aspx)。 - CodeCaster
1
因为在客户端生成了一个只有属性的类(除非您引用包含数据契约并选择在生成客户端时重用类型,但那是另一回事),没有构造函数或方法。如果您将Item作为服务操作参数(IService1.Foo(Item item))使用,那么当您调用该操作时就会在运行时崩溃,因为序列化程序无法在服务端找到Item上的无参构造函数。 - CodeCaster
2
是的。序列化程序使用反射来实例化新实例,并使用无参数构造函数来执行此操作。但这并不正确。在WCF中,一些黑魔法被用于创建对象的实例。请参见https://dev59.com/BHNA5IYBdhLWcg3wIqTr。 - Jehof
@Jehof 不错的补充,谢谢。我知道这个,但是WCF仍然需要存在一个无参数构造函数。已更新答案。 - CodeCaster
显示剩余3条评论

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