RuntimeTypeModel
API의 버그 또는 제한 사항 일 수 있습니다.
ValueMember
이 컬렉션인지 여부를 확인하는 방법은 RuntimeTypeModel.ResolveListTypes()
입니다. 들어오는 itemType
이 null 일 때 컬렉션 항목 유형을 추론합니다. 수행하여 예를 들어, 정적 속성을 사용 NotACollectionHolder
에 대한 계약을 구축 할 때 :
var model = TypeModel.Create();
var schema = model.GetSchema(typeof(NotACollectionHolder));
다음 ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour(bool isEnum, ProtoMemberAttribute normalizedAttribute)
는이 ValueMember
를 초기화 만들라고합니다.
// check for list types
ResolveListTypes(model, effectiveType, ref itemType, ref defaultType);
// but take it back if it is explicitly excluded
if(itemType != null)
{ // looks like a list, but double check for IgnoreListHandling
int idx = model.FindOrAddAuto(effectiveType, false, true, false);
if(idx >= 0 && model[effectiveType].IgnoreListHandling)
{
itemType = null;
defaultType = null;
}
}
공지 사항 IgnoreListHandling
에 대한 명시 적 검사에는 다음과 같은 논리가? 이렇게하면 some_objects
이 컬렉션으로 직렬화되지 않게됩니다.
var model = TypeModel.Create();
var meta = model.Add(typeof(NotACollectionHolder), false);
var member = meta.AddField(1, "some_objects", null, null);
var schema = model.GetSchema(typeof(NotACollectionHolder));
을 다음 MetaType.AddField(int fieldNumber, string memberName, Type itemType, Type defaultType, object defaultValue)
가 호출 될 때, 단순히 않는 : IgnoreListHandling
에 대한 확인이없는
ResolveListTypes(model, miType, ref itemType, ref defaultType);
공지 사항을 다음과 같이
반대로, 경우 프로그래밍 ValueMember
을 추가? 이것이 문제의 원인입니다.
불행히도 ValueType.itemType
은 읽기 전용이며 MetaType[int fieldNumber]
은 get 전용이므로이 문제를 해결하기 위해 간단한 API가없는 것 같습니다. reporting an issue을 고려해보십시오.내가 찾을 수
유일한 해결 방법은 지금처럼 NotACollectionHolder
유형에 대한 대리를 소개하는 것입니다 : 다음
[ProtoContract]
internal class NotACollectionHolderSurrogate
{
[ProtoMember(1)]
internal NotACollectionSurrogate some_objects;
public static implicit operator NotACollectionHolder(NotACollectionHolderSurrogate input)
{
if (input == null)
return null;
return new NotACollectionHolder { some_objects = input.some_objects };
}
public static implicit operator NotACollectionHolderSurrogate(NotACollectionHolder input)
{
if (input == null)
return null;
return new NotACollectionHolderSurrogate { some_objects = input.some_objects };
}
}
[ProtoContract]
internal class NotACollectionSurrogate
{
[ProtoMember(1)]
public int some_data;
public static implicit operator NotACollection(NotACollectionSurrogate input)
{
if (input == null)
return null;
return new NotACollection { some_data = input.some_data };
}
public static implicit operator NotACollectionSurrogate(NotACollection input)
{
if (input == null)
return null;
return new NotACollectionSurrogate { some_data = input.some_data };
}
}
그리고는 수행
var model = TypeModel.Create();
model.Add(typeof(NotACollectionHolder), false).SetSurrogate(typeof(NotACollectionHolderSurrogate));
var schema = model.GetSchema(typeof(NotACollectionHolder));
생성 된 계약은 필요하다 :
message NotACollectionHolderSurrogate {
optional NotACollectionSurrogate some_objects = 1;
}
message NotACollectionSurrogate {
optional int32 some_data = 1 [default = 0];
}