2013-04-29 4 views
1

나는 기본 모델에 System.Drawing.Color를 추가 할 필요가 있지만, 그 값은 읽기 전용, 그래서 나는 다음을 수행하려고에 대한 :InvalidOperationException이 때 SetFactory RuntimeTypeModel

MetaType colorMeta = RuntimeTypeModel.Default.Add(typeof(Color), true); 

MethodInfo methodInfo = typeof(Color).GetMethod("FromArgb", new Type[] { typeof(Int32), typeof(Int32), typeof(Int32), typeof(Int32) }); 

colorMeta.AddField(1, "A"); 
colorMeta.AddField(2, "R"); 
colorMeta.AddField(3, "G"); 
colorMeta.AddField(4, "B"); 

colorMeta.SetFactory(methodInfo); 

내가 얻을 :

InvalidOperationException : Operation is not valid due to the current state of the object 

답변

1

거기에 몇 가지 문제가 있습니다. 첫 번째로이 컨텍스트의 "팩토리"는 유형의 인스턴스를 만드는 정적 메서드 여야하지만 이 아니며이 값과 함께 수행됩니다. FromArgb과 같은 메서드에는 사용할 수 없습니다.

둘째, protobuf-NET은 세터 부족하기 때문에 A/R/G/B 특성을 가진 많은 일을 할 수 없습니다.

당신의 생각은 장점이 있습니다. 이것은 기존의 자동 터플 기능과 매우 흡사합니다. 자동 튜플 코드가 명백한 모든 멤버와 일치하는 생성자가되기를 원하는 주요 차이점이 있습니다. Color에는 이러한 생성자가 없지만 생성자 대신 팩터 리 메서드를 허용하도록 튜플 코드를 확장 할 수 있는지 알아 보는 것이 좋습니다.

  • 민간 필드를 직렬화 모델을 이야기하고,
  • 이 대리
  • 를 사용하는 생성자를 건너 뛸 :

    그러나, 지금은 (어떤 코드를 변경하지 않고) 아마이 가능한 옵션이 있습니다

나는 아마 후자가 더 쉬울 것이라고 제안 할 것이다. 예를 들어 다음 작업 (모든 색상에서 잘 작동하므로 고정 4 바이트 레이아웃 사용)이 적용됩니다.

using ProtoBuf; 
using ProtoBuf.Meta; 
using System.Drawing; 

[ProtoContract] 
struct ColorSurrogate 
{ 
    public int Value { get { return value; } } 
    [ProtoMember(1, DataFormat = DataFormat.FixedSize)] 
    private int value; 
    public ColorSurrogate(int value) { this.value = value; } 

    public static explicit operator Color(ColorSurrogate value) { 
     return Color.FromArgb(value.Value); 
    } 
    public static explicit operator ColorSurrogate(Color value) { 
     return new ColorSurrogate(value.ToArgb()); 
    } 
} 
[ProtoContract] 
class Foo { 
    [ProtoMember(1)] 
    public Color Color { get; set; } 
} 

class Program { 
    static void Main() { 
     RuntimeTypeModel.Default.Add(typeof(Color), false) 
      .SetSurrogate(typeof(ColorSurrogate)); 

     var foo = new Foo { Color = Color.Firebrick }; 
     var clone = Serializer.DeepClone(foo); 
    } 
} 
관련 문제