次のクラスのためにjsonを逆シリアル化する必要があります。
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であるオブジェクトを取得しているため、Testクラスのオブジェクトを作成するにはどうすればよいですか?
NewtonsoftJsonパーサーを使用しています。
[JsonConstructor]
属性でマークすることにより、Json.Netにプライベートコンストラクターを呼び出させることができます。
[JsonConstructor]
private Test()
{
//NOTHING TO INITIALIZE
}
シリアライザーは、コンストラクターを呼び出した後も、パブリックセッターを使用してオブジェクトにデータを入力することに注意してください。
[〜#〜]編集[〜#〜]
別の可能なオプションは、ConstructorHandling
設定を使用することです。
JsonSerializerSettings settings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
Test t = JsonConvert.DeserializeObject<Test>(json, settings);
追加の手順を実行する必要はないようです。
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;
}
}
ここでSerializer設定を作成し、assignConstructorHandlingを指定する必要はありません。プライベートコンストラクターに[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;
}
}
最高です!