그래서 사용자가 다른 serialize를 구현하고 선택할 수 있도록 Unity3D 용 사용자 지정 serialization 시스템을 작성하고 있습니다. 현재 BinaryFormatter
및 protobuf-net
을 지원합니다. 하나; 이 시스템에서 나는 내 시리얼 라이저와 함께 멋진 연주하고 싶습니다 직렬화에 대한 지속적인 사용자 정의 규칙을 가지고 : 직렬화하지 않습니다 그들은 부작용 [Serializable]
protobuf-net 사용자 지정 serialization 및 모델 구성
- 유형 직렬화하고, 단지 자동차들
- 공공 분야/자동 속성을 암시 적으로 직렬화 사용자 정의 속성이 (내가 사람들의 다양한이 그들에 적용 할 때
- 비 공공 분야/자동 속성은 직렬화 :
[Save]
,[Serialize]
및[SerializeField]
01 내가 protobufs의 정의
ProtoContract
같은 속성을 사용하지 않도록 23,516,
지금은 등 ProtoMember
,이 규칙에 적응하는 내 protobuf - 네트 모델을 적응하기 위해 내가 상상하는 방법을 싶습니다 사용자가 자신의 커스텀 타입을 추가 할 수있는 직렬화 가능한 타입의 배열을 가지는 것입니다. (그런 식으로 그 타입에 대해 ProtoContract를 필요로하지 않습니다.) 그런 타입을 반복하여 내 모델에 추가 할 것입니다. Foreach 유형, 나는 내 직렬화 규칙을 만족시키는 멤버를 얻고이를 모델에 추가한다.
내가하고 싶은 또 다른 것은, 당신은 사용자가 단지 A
를 추가, 명시 적으로 B
및 C
을 추가 할 필요가 없습니다 내가 A
의 아이를 얻을 것입니다 어린이 B
및 C
와 추상 클래스 A
을 가지고 말하는 것입니다 그들을 직접 추가하십시오.
[Serializble]
public abstract class AbstractBase
{
public abstract int Num { get; set; }
}
[Serializble]
public class Child1 : AbstractBase
{
public int x;
public override int Num { get { return x; } set { x = value; } }
}
[Serializble]
public class Child2 : AbstractBase
{
public int y;
public int z;
public override int Num { get { return y; } set { y = value; } }
}
// ProtobufSerializableTypes.cs
public static Type[] SerializableTypes = new[]
{
typeof(AbstractBase)
};
해봤 내용은 다음과 같습니다 :
[ProtoContract]
[ProtoInclude(1, typeof(Child1))]
[ProtoInclude(2, typeof(Child2))]
public abstract class AbstractBase
{
public abstract int Num { get; set; }
}
[ProtoContract]
public class Child1 : AbstractBase
{
[ProtoMember(1)]
public int x;
public override int Num { get { return x; } set { x = value; } }
}
[ProtoContract]
public class Child2 : AbstractBase
{
[ProtoMember(1)]
public int y;
[ProtoMember(2)]
public int z;
public override int Num { get { return y; } set { y = value; } }
}
내가 그들을이 쓸 수 있도록하고 싶습니다 대신 사용자가이 작성해야하는 :
내 질문에 귀결
[TestClass]
public class ProtobufDynamicSerializationTestSuite
{
private AbstractBase Base { get; set; }
private Type[] SerializableTypes { get; set; }
[TestInitialize]
public void Setup()
{
Base = new Child1();
SerializableTypes = new[]
{
typeof(AbstractBase)
};
}
[TestMethod]
public void ShouldCopyWithCustomConfig()
{
var model = TypeModel.Create();
Func<Type, MetaType> addType = type =>
{
log("adding type: {0}", type.Name);
return model.Add(type, false);
};
var hierarchy = new Dictionary<MetaType, List<Type>>();
for (int i = 0; i < SerializableTypes.Length; i++)
{
var type = SerializableTypes[i];
var meta = addType(type);
var temp = new List<Type>();
var children = type.Assembly.GetTypes().Where(t => t.IsSubclassOf(type) && !t.IsAbstract).ToList();
for(int j = 0; j < children.Count; j++)
{
var child = children[j];
addType(child);
log("adding subtype {0} with id {1}", child.Name, j + 1);
meta.AddSubType(j + 1, child);
temp.Add(child);
}
hierarchy[meta] = temp;
}
Func<Type, string[]> getMemberNames = x =>
//SerializationLogic.GetSerializableMembers(x, null) // real logic
x.GetMembers(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public) // dummy logic
.Where(m => m.MemberType == MemberTypes.Field)
.Select(m => m.Name)
.ToArray();
foreach (var entry in hierarchy)
{
int id = 1;
foreach (var type in entry.Value)
{
foreach (var member in getMemberNames(type))
{
log("adding member {0} to type {1} with id {2}", member, type.Name, id);
entry.Key.Add(id++, member);
}
}
}
Base.Num = 10;
var copy = (AbstractBase)model.DeepClone(Base);
Assert.AreEqual(copy.Num, 10);
}
void log(string msg, params object[] args)
{
Console.WriteLine(string.Format(msg, args));
}
void log(string msg)
{
log(msg, new object[0]);
}
}
그래서 모든 필요한 유형을 모델에 추가하고 모든 하위 유형을 상위 유형에 추가했습니다. 의 다음 추가 된 모든 유형의 반복과 모델에 추가이가 그러나 실패 유형
에서 (내 직렬화 규칙에 해당) 해당 필드/속성 :
Test Name: ShouldCopyWithCustomConfig
Test Outcome: Failed
Result Message:
Test method ProtobufTests.ProtobufDynamicSerializationTestSuite.ShouldCopyWithCustomConfig threw exception:
System.ArgumentException: Unable to determine member: x
Parameter name: memberName
Result StandardOutput:
adding type: AbstractBase
adding type: Child1
adding subtype Child1 with id 1
adding type: Child2
adding subtype Child2 with id 2
adding member x to type Child1 with id 1
어떻게 생각 잘못하고있는거야? 이렇게하는 더 좋은 방법이 있습니까?
감사합니다.A
가 있고, 종류 A
및 B
, 처음에 나는이 사전 단계가 없었
참고, 내가 바로 모델에 추가 한 후 유형의 구성원을 추가했지만, 내가 말할 경우이 실패 B
참조, 형식 A
및 그 구성원을 추가하려고하면 B
을 따라 올 테지만 protobuf는이 단계에서 식별 할 수 없습니다. 아직 모델에 추가되지 않았기 때문에 ... 그래서 추가 할 필요가 있다고 생각했습니다. 먼저 유형을 입력 한 다음 구성원을 입력하십시오.
안녕하세요; 나는 protobuf-net의 저자 다. 오늘 하루 종일 Redis 워크숍에 출근 할 수 없으므로 최대한 빨리 할 것입니다. –
알려 주셔서 고마워요! 나는 당신의 대답을 기다리고 싶었습니다 : D 나는 당신이 나를 때리는 동안 내 자신의 것을 시도 할 것입니다. – vexe
@MarcGravell은 여전히 그것을 알아 내지 못했습니다. 약간의 도움을 사용할 수 있습니다; P – vexe