将json反序列化为具有默认私有构造函数的类的C#对象
我需要为下面的类反序列化json将json反序列化为具有默认私有构造函数的类的C#对象,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我需要为下面的类反序列化json public class Test { public string Property { get; set; } private Test() { //NOTHING TO INITIALIZE } public Test(string prop) { Property = prop; } } 我可以创建一个测试实例,如 var instance = new Test(
public class Test
{
public string Property { get; set; }
private Test()
{
//NOTHING TO INITIALIZE
}
public Test(string prop)
{
Property = prop;
}
}
我可以创建一个测试实例,如
var instance = new Test("Instance");
考虑到我的json
"{ "Property":"Instance" }"
我应该如何创建测试类的对象,因为我的默认构造函数是私有的,并且我得到的对象属性为NULL
我正在使用Newtonsoft Json解析器。您可以通过使用
[JsonConstructor]
属性标记Json.Net来调用私有构造函数:
[JsonConstructor]
private Test()
{
//NOTHING TO INITIALIZE
}
请注意,序列化程序在调用构造函数后仍将使用公共setter填充对象
另一个可能的选项是使用
ConstructorHandling
设置:
JsonSerializerSettings settings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
Test t = JsonConvert.DeserializeObject<Test>(json, settings);
JsonSerializerSettings设置=新的JsonSerializerSettings
{
ConstructorHandling=ConstructorHandling.AllowNonPublicDefaultConstructor
};
Test t=JsonConvert.DeserializeObject(json,设置);
您似乎不需要采取任何额外的步骤
使用Json.NET v6.0.8,以下C#程序在LINQPad中工作:
void Main()
{
var o = JsonConvert.DeserializeObject<Test>("{\"Property\":\"Instance\"}");
Debug.Assert(o.Property == "Instance",
"Property value not set when deserializing.");
}
public class Test
{
public string Property { get; set; }
private Test()
{
}
public Test(string propertyValue)
{
Property = propertyValue;
}
}
void Main()
{
var o=JsonConvert.DeserializeObject(“{\”属性\“:\”实例\“}”);
Assert(o.Property==“实例”,
“反序列化时未设置属性值。”);
}
公开课考试
{
公共字符串属性{get;set;}
私人测试()
{
}
公共测试(字符串属性值)
{
属性=属性值;
}
}
无需创建序列化程序设置并在此处指定assign Constructor Handling。请记住为私有构造函数定义[JsonConstructor]
属性。
我对抽象BaseNode.cs及其具体ComputerNode.cs实现也有类似的情况。您可以创建类,复制/粘贴下面的代码,并进行一些实验
public abstract class BaseNode
{
[JsonConstructor] // ctor used when Json Deserializing
protected BaseNode(string Owner, string Name, string Identifier)
{
this.Name = Name;
this.Identifier = Identifier;
}
// ctor called by concrete class.
protected BaseNode(string [] specifications)
{
if (specifications == null)
{
throw new ArgumentNullException();
}
if (specifications.Length == 0)
{
throw new ArgumentException();
}
Name = specifications[0];
Identifier = specifications[1];
}
public string Name{ get; protected set; }
public string Identifier { get; protected set; }
}
public class ComputerNode: BaseNode
{
public string Owner { get; private set; }
[JsonConstructor] // not visible while creating object from outside and only used during Json Deserialization.
private ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier)
{
this.Owner = Owner;
}
public ComputerNode(string[] specifications):base(specifications)
{
Owner = specifications[2];
}
}
对于JSon读写,以下代码有助于-
public class Operation<T>
{
public string path;
public Operation()
{
var path = Path.Combine(Directory.GetCurrentDirectory(), "nodes.txt");
if (File.Exists(path) == false)
{
using (File.Create(path))
{
}
}
this.path = path;
}
public void Write(string path, List<T> nodes)
{
var ser = JsonConvert.SerializeObject(nodes, Formatting.Indented);
File.WriteAllText(path, ser);
}
public List<T> Read(string path)
{
var text = File.ReadAllText(path);
var res = JsonConvert.DeserializeObject<List<T>>(text);
return res;
}
}
公共类操作
{
公共字符串路径;
公共业务()
{
var path=path.Combine(Directory.GetCurrentDirectory(),“nodes.txt”);
if(File.Exists(path)==false)
{
使用(File.Create(path))
{
}
}
this.path=path;
}
公共无效写入(字符串路径、列表节点)
{
var ser=JsonConvert.serialized对象(节点、格式、缩进);
writealText(路径,ser);
}
公共列表读取(字符串路径)
{
var text=File.ReadAllText(路径);
var res=JsonConvert.DeserializeObject(文本);
返回res;
}
}
祝你一切顺利今天的简短回答是:将构造函数参数
prop
重命名为property
,您的代码将正常工作
公共类测试
{
公共字符串属性{get;}
公共测试(字符串属性)
{
财产=财产;
}
}
控制台写入线(
反序列化对象(新测试(“实例”);
Json支持使用现成的构造函数参数初始化属性,而无需设置任何附加属性或更改任何设置。唯一的限制是参数名必须与属性名不区分大小写匹配。您使用的是什么库?如何获得
Test
的实例?如果没有任何工厂生成Test
对象,您希望如何将JSON反序列化到它的实例中?如果要序列化的对象位于不希望引入第三方依赖项的库/程序集中,则第二个选项是最佳选择(包括对Json.Net的依赖项…)在线修改示例示例:请注意,在此示例中,未使用带有propertyValue
参数的公共构造函数。相反,私有构造函数与属性
ter一起使用。如果要使其与get
一起使用,请参阅我对该问题的回答>只有属性。