C# POCO可以包含构造函数吗?

C# POCO可以包含构造函数吗?,c#,poco,C#,Poco,POCO可以包含构造函数吗?你能告诉我这门课是否正确吗?我还读到POCO必须有一个无参数构造函数。这是正确的吗?为什么?如果我接受这个无参数构造函数,我的只读Id属性就会有问题。对我来说,如果这个属性必须是只读的,那么初始化它的唯一方法就是在构造函数中 [DataContract] public class MembershipUser { public MembershipUser(Guid idValue) { this.Id = idValue; }

POCO可以包含构造函数吗?你能告诉我这门课是否正确吗?我还读到POCO必须有一个无参数构造函数。这是正确的吗?为什么?如果我接受这个无参数构造函数,我的只读
Id
属性就会有问题。对我来说,如果这个属性必须是只读的,那么初始化它的唯一方法就是在构造函数中

[DataContract]
public class MembershipUser
{
    public MembershipUser(Guid idValue)
    {
        this.Id = idValue;
    }

    [DataMember]
    public virtual readonly Guid Id { get; set; }

    [DataMember]
    public virtual string UserName { get; set; }

    [DataMember]
    public virtual string Email { get; set; }
}

POCO对象可以包含其他构造函数,但反序列化需要默认构造函数,因为该进程尝试创建对象的默认实例,然后设置属性

经过一些研究,似乎datacontract序列化程序不使用甚至不调用默认构造函数。使用这种方法,您可以排除默认的ctor,并且仍然可以序列化POCO。您是否应该是您和您的团队必须决定的实施细节

DataContractSerializer测试:

[Test]
public void SerializerTest()
{
    var s = new SerializeMe(2);
    s.Name = "Test";
    DataContractSerializer dcs = new DataContractSerializer(typeof(SerializeMe));
    Stream ms = new MemoryStream();
    var writer = XmlWriter.Create(ms);
    Assert.DoesNotThrow(() => dcs.WriteObject(writer, s));
    writer.Close();

    ms.Position = 0;
    var reader = new StreamReader(ms);
    var xml = reader.ReadToEnd();
    Console.WriteLine(xml);
}

[Test]
public void DeserializeTest()
{
    var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><SerializeMe xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/Test\"><Id>2</Id><Name>Test</Name></SerializeMe>";
    DataContractSerializer dcs = new DataContractSerializer(typeof(SerializeMe));            
    XmlReader reader = XmlReader.Create(new StringReader(xml));
    var obj = dcs.ReadObject(reader) as SerializeMe;
    Assert.AreEqual(obj.Name, "Test");
}

[DataContract]
public class SerializeMe
{
    public SerializeMe(int id)
    {
        this.Id = id;
    }
    [DataMember]
    public int Id { get; private set; }
    [DataMember]
    public string Name { get; set; }
}
[测试]
public void SerializerTest()
{
var s=新的序列化me(2);
s、 Name=“测试”;
DataContractSerializer dcs=新的DataContractSerializer(typeof(SerializeMe));
流ms=新的内存流();
var writer=XmlWriter.Create(ms);
Assert.DoesNotThrow(()=>dcs.WriteObject(writer,s));
writer.Close();
ms.Position=0;
var读取器=新的StreamReader(毫秒);
var xml=reader.ReadToEnd();
Console.WriteLine(xml);
}
[测试]
public void反序列化测试()
{
var xml=“2Test”;
DataContractSerializer dcs=新的DataContractSerializer(typeof(SerializeMe));
XmlReader=XmlReader.Create(新的StringReader(xml));
var obj=dcs.ReadObject(reader)作为SerializeMe;
Assert.AreEqual(obj.Name,“Test”);
}
[数据合同]
公共类序列化我
{
公共序列化名称(int-id)
{
这个.Id=Id;
}
[数据成员]
public int Id{get;private set;}
[数据成员]
公共字符串名称{get;set;}
}

它会编译吗?对我们知道它是否适合您的需要吗?当然不是。就目前而言,这不是一个好问题。如果您首先在实体框架代码的上下文中引用POCO,那么不,实体框架将不支持您的类。您需要一个无参数构造函数。WCF也不需要,它基于您所针对的
[DataContract]
属性。POCO不是严格定义的术语(即SO定义的变体在链接中)。因此,“POCO是否可以拥有XXXX”的答案不能比链接的问题更好。如果您使用特定的框架,POCO可能意味着“普通对象”的某些特定子集,可能需要也可能不需要特定的特性,例如是否存在默认构造函数。如果需要,请随时单独询问更具体的版本。旁注:我个人不会将此类对象称为“POCO”,因为您的代码暗示继承,并且感觉超出了“普通”对象的范围。请更正,但我仍然可以编写自己的反序列化过程。@B413是的,您可以这样做,但您为什么要这样做?Net中内置了大量的序列化机制,没有必要重新发明轮子。我喜欢这个“没有必要重新发明轮子”。相信我,总有一个重新发明轮子的理由。最好的例子可能是.NET框架。我认为这句话应该从中删除。。。和大多数其他工程工作。