.NET 사용자 정의 직렬화를 사용할 때 선택적 필드를 테스트하십시오
-
20-09-2019 - |
문제
이와 같은 수업이 주어지면 :
[Serializable]
public class MyClass {
string name;
string address;
public MyClass(SerializationInfo info, StreamingContext context){
name = info.GetString("name");
if(/* todo: check if a value for address exists */)
address = info.GetString("address");
}
public void GetObjectData(SerializationInfo info, StreamingContext context){
info.AddValue(name);
if(address != null)
info.AddValue(address);
}
}
값의 값 여부를 어떻게 테스트합니까? address
필드는 전화하기 전에 존재합니다 info.GetString(address)
?
예, 나는 단순히 널을 쓸 수 있다는 것을 이해합니다. address
필드이지만 내 진짜 문제는 MyClass
, 주소 필드가 없었습니다.
메모: 맞춤 직렬화를 사용해야 할 충분한 이유가 있습니다. 싱글 톤으로 사용되는 일부 정적 필드가 있으며 기본 사산화는이를 존중하지 않을 것입니다.
해결책
글쎄, 흥미로운 접근법 중 하나는 당신이 사용할 수 있다는 것입니다. GetEnumerator
(foreach
) 이름/값 쌍을 반복하기 위해 switch
각각을 차례로 처리 할 이름이 있습니까?
그러나 구현은 약간 비표준으로 보인다. 예에서 여기:
SerializationInfoEnumerator e = info.GetEnumerator();
Console.WriteLine("Values in the SerializationInfo:");
while (e.MoveNext())
{
Console.WriteLine("Name={0}, ObjectType={1}, Value={2}",
e.Name, e.ObjectType, e.Value);
}
그러나 당신이 사용할 수있는 것 같습니다 SerializationEntry
:
[Serializable]
class MyData : ISerializable
{
public string Name { get; set; }
public int Value { get; set; }
public MyData() { }
public MyData(SerializationInfo info, StreamingContext context)
{
foreach (SerializationEntry entry in info)
{
switch (entry.Name)
{
case "Name":
Name = (string)entry.Value; break;
case "Value":
Value = (int)entry.Value; break;
}
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", Name);
info.AddValue("Value", Value);
}
}
다른 팁
나는 이것이 매우 오래된 스레드라는 것을 알고 있지만이 문제에 대한 나의 해결책은 직렬화 info 다음과 같은 클래스 :
namespace System.Runtime.Serialization
{
public static class SerializationInfoExtensions
{
public static bool Exists(this SerializationInfo info, string name)
{
foreach (SerializationEntry entry in info)
if (name == entry.Name)
return true;
return false;
}
}
}
제휴하지 않습니다 StackOverflow