Protobuf-net으로 직렬화를 수행하지 않고이 코드 스 니펫에 대해 다음 오류가 발생합니다.
오류:
동적 유형이 계약 유형이 아닙니다. TestType []
스 니펫 :
using System.IO;
namespace QuickStart
{
class Program
{
static void Main()
{
//FileAccess.ShowFileAccess();
//Sockets.ShowSockets();
var dto = new DataTransferType
{
ProtoDynamicProperty = new TestType[]
{
new TestType {UselessProperty="AAA"},
new TestType{UselessProperty="BBB"},
new TestType{UselessProperty="CCC"}
}
};
using (MemoryStream testStream = new MemoryStream())
{
ProtoBuf.Serializer.SerializeWithLengthPrefix(testStream, dto, ProtoBuf.PrefixStyle.Base128);
}
}
}
[ProtoBuf.ProtoContract]
struct TestType
{
[ProtoBuf.ProtoMember(1)]
public string UselessProperty { get; set; }
}
[ProtoBuf.ProtoContract]
class DataTransferType
{
[ProtoBuf.ProtoMember(1, DynamicType = true)]
public object ProtoDynamicProperty { get; set; }
}
}
왜 이런 일이 발생하는지 아이디어가 있습니까? 2.0.0.651 빌드를 사용하고 있습니다.
귀하의 어려움은 protobuf-net 의 이전 프로젝트 사이트 에서 여기 에 DynamicType
언급 된 제한 사항에 의해 설명됩니다 (완전하지는 않지만) .
DynamicType
-Type
유형과 함께 추가 정보를 저장 합니다 (AssemblyQualifiedName
사용자가 제어 할 수 있지만 기본적으로를 포함합니다 ). 이를 통해 약한 모델을 직렬화 할 수 있습니다. 즉,object
속성 멤버에 사용되는 위치 가 있지만 현재 이것은 계약 유형 (기본 형식이 아님)으로 제한되고 상속이있는 유형에 대해서는 작동하지 않습니다 (이러한 제한은 나중에 제거 될 수 있음). 와 마찬가지로AsReference
이것은 매우 다른 레이아웃 형식을 사용합니다.
그렇다면 계약 유형 이 정확히 무엇을 의미 합니까? 언급했듯이 기본 유형은 계약 유형이 아니지만 그게 전부입니까? 에서 비공식 수동 : : protobuf - 그물 형의 직렬화의 양식 Protobuf-NET :
protobuf-net이 유형별로 지원하는 기본 유형을 포함하지 않는 5 가지 기본 유형의 [역 직렬화]가 있다고 말할 수 있습니다.
일반 직렬화. 이 모드에서는 ProtoMember로 표시했거나 ImplicitFields에서 자동으로 선택한 각 필드 또는 속성에 대한 프로토콜 버퍼의 한 필드와 함께 표준 프로토콜 버퍼가 작성됩니다. ...
컬렉션 직렬화. protobuf-net이 특정 데이터 유형을 컬렉션으로 식별하면이 모드를 사용하여 직렬화됩니다. 고맙게도 컬렉션 유형에는 ProtoContract 또는 ProtoMember 속성이 필요하지 않습니다. 즉, List 및 T []와 같은 유형을 쉽게 직렬화 할 수 있습니다.
<snip>
Protobuf-net은 "반복"필드 (프로토콜 버퍼 용어)를 사용하여 컬렉션을 직렬화합니다. 따라서 버전간에 컬렉션 유형을 안전하게 변경할 수 있어야합니다. 예를 들어, Foo []를 직렬화하고 나중에 목록으로 역 직렬화 할 수 있습니다.
따라서 "계약 유형"의 직렬화는이 기사의 "정상 직렬화"에 해당하며 컬렉션은 계약 유형 이 아닙니다 . 이것은 Dynamic type is not a contract-type: TestType[]
예외 메시지를 설명합니다 .
해결 방법으로 다음 ProtoDynamicProperty
과 같이 계약 유형에 해당하는 것이 보장되고 필수 유형 정보를 캡슐화하는 일반 대리 유형 내부를 패키징 할 수 있습니다 .
[ProtoContract]
public abstract class TypedObjectSurrogate
{
protected TypedObjectSurrogate() { }
[ProtoIgnore]
public abstract object ObjectValue { get; }
public static object CreateSurrogate<T>(T value)
{
if (value == null)
return new TypedObjectSurrogate<T>();
var type = value.GetType();
if (type == typeof(T))
return new TypedObjectSurrogate<T>(value);
// Return actual type of subclass
return Activator.CreateInstance(typeof(TypedObjectSurrogate<>).MakeGenericType(type), value);
}
}
[ProtoContract]
public sealed class TypedObjectSurrogate<T> : TypedObjectSurrogate
{
public TypedObjectSurrogate() : base() { }
public TypedObjectSurrogate(T value)
: base()
{
this.Value = value;
}
[ProtoIgnore]
public override object ObjectValue
{
get { return Value; }
}
[ProtoMember(1)]
public T Value { get; set; }
}
[ProtoBuf.ProtoContract]
class DataTransferType
{
[ProtoBuf.ProtoIgnore]
public object ProtoDynamicProperty { get; set; }
[ProtoBuf.ProtoMember(1, DynamicType = true)]
object ProtoDynamicPropertySurrogate
{
get
{
if (ProtoDynamicProperty == null)
return null;
return TypedObjectSurrogate.CreateSurrogate(ProtoDynamicProperty);
}
set
{
if (value is TypedObjectSurrogate)
ProtoDynamicProperty = ((TypedObjectSurrogate)value).ObjectValue;
else
ProtoDynamicProperty = value;
}
}
}
[ProtoBuf.ProtoContract]
struct TestType
{
[ProtoBuf.ProtoMember(1)]
public string UselessProperty { get; set; }
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다