WCF反序列化有一些神奇之处.如何在不调用其构造函数的情况下实例化数据协定类型的实例?
例如,考虑这个数据合同:
[DataContract]
public sealed class CreateMe
{
[DataMember] private readonly string _name;
[DataMember] private readonly int _age;
private readonly bool _wasConstructorCalled;
public CreateMe()
{
_wasConstructorCalled = true;
}
// ... other members here
}
Run Code Online (Sandbox Code Playgroud)
通过DataContractSerializer您获取此对象的实例时,您将看到该字段_wasConstructorCalled是false.
那么,WCF如何做到这一点?这是其他人可以使用的技术,还是隐藏在我们之外?
我有以下WCF DataContract:
[DataContract]
public class Occupant
{
private string _Name;
private string _Email;
private string _Organization;
private string _Badge;
public Occupant(string name, string badge, string organization)
{
Name = name;
Badge = badge;
Organization = organization;
}
public Occupant(string name, string badge)
{
Value = name;
Key = badge;
}
[DataMember]
public string Key
{
get { return _Name; }
set { _Name = value; }
}
[DataMember]
public string Value
{
get { return _Badge; }
set { _Badge …Run Code Online (Sandbox Code Playgroud) 当BinaryFormatter反序列化流为对象,似乎没有调用构造函数来创建新的对象.
它是怎么做到的?为什么?.NET中还有其他功能吗?
这是一个演示:
[Serializable]
public class Car
{
public static int constructionCount = 0;
public Car()
{
constructionCount++;
}
}
public class Test
{
public static void Main(string[] args)
{
// Construct a car
Car car1 = new Car();
// Serialize and then deserialize to create a second, identical car
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, car1);
stream.Seek(0, SeekOrigin.Begin);
Car car2 = (Car)formatter.Deserialize(stream);
// Wait, what happened?
Console.WriteLine("Cars constructed: " + Car.constructionCount);
if …Run Code Online (Sandbox Code Playgroud) DataContractSerializer 反序列化时不调用构造函数或调用字段初始值设定项:
DataContractSerializer不调用我的构造函数?
使用DataContractSerializer时设置属性的初始值
是否可以readonly在对象反序列化后初始化字段?我必须放弃该语言功能才能使用DataContractSerializer吗?
我得到一个null异常,但该字段被初始化为一个空列表.那怎么可能是null?
此方法中的第二行发生错误(在_hydratedProperties上):
protected virtual void NotifyPropertyChanged<T>(Expression<Func<T>> expression)
{
string propertyName = GetPropertyName(expression);
if (!this._hydratedProperties.Contains(propertyName)) { this._hydratedProperties.Add(propertyName); }
}
Run Code Online (Sandbox Code Playgroud)
这就是宣布该领域的方式:
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
private List<string> _hydratedProperties = new List<string>();
Run Code Online (Sandbox Code Playgroud)
这是如何设置:
public Eta Eta
{
get { return this._eta; }
set
{
this._eta = value;
NotifyPropertyChanged(() => this.Eta);
}
}
Run Code Online (Sandbox Code Playgroud)
这是完整的类(删除了注释和非相关部分):
[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
private List<string> _hydratedProperties = new List<string>();
public bool IsPropertyHydrated(string propertyName)
{ …Run Code Online (Sandbox Code Playgroud) 有人告诉我,包含getter和setter的可序列化对象需要一个空白构造函数,如下所示:
[DataContract]
public class Item
{
[DataMember]
public string description { get; set; }
public Item() {}
public Item(string description)
{
this.description = description;
}
}
Run Code Online (Sandbox Code Playgroud)
并且告诉我的原因是这允许使用setter构造对象.但是,我发现Item定义如下:
[DataContract]
public class Item
{
[DataMember]
public string description { get; set; }
public Item(string description)
{
this.description = description;
}
}
Run Code Online (Sandbox Code Playgroud)
当通过WCF服务引用作为代理类提供时,可以在不调用构造函数的情况下构造:
Item item = new Item {description = "Some description"};
Run Code Online (Sandbox Code Playgroud)
问题:
new
Item我发现如果类不是代理类,我不能在没有构造函数的情况下创建对象.