2016-11-02 13 views
0

C#WCFオブジェクト[]メンバ型のシリアライズ

[DataContract] 
public class Sample 
{ 
    [DataMember] 
    public object[] Values { get; set; } 
} 

「オブジェクト」を直接シリアライズすることはできません...しかし、それを動作させる方法具体的なボックス化された値がそれぞれ 'int'、 'double'、 'string'、 'DataTime'のいずれかになると考えていますか?

答えて

0

簡易回答:具体的な直列化可能な型を使用してください。

コンプレックス回答:データの

ネットワーク伝送を正確に接続の両端にオブジェクトを再作成するために必要なすべての情報がシリアル化が成功するために送信する必要があることを必要とします。このため、具体的な直列化可能な型を使用する必要があります。

+0

ありがとうございます。 – lemon

+0

1つではありません - 設計通りです。 *なぜ* *オブジェクトから直列化可能な型を判断しようとする複雑さが、オブジェクトをネットワークのデータストリームに変換して再び元に戻すプロセスが非常に高価で複雑なものになるかについて、分かりましょう。 – toadflakz

+0

私は最終的にそれを行う方法を見つけました...私はそれを期待していませんでしたが、それは動作します:私はそれについての答えを追加します – lemon

0

最後に、私はそれを行う簡単な方法を見つけました。

"KnownType"属性を知っていましたが、この属性が配列の各オブジェクト値ではなくメンバタイプ全体(つまり "object []")を指定するものだと思ったので、 。

しかし、シリアライゼーションでは、それぞれの未知の値に対して既知の型を使用するので、非常にうまくいくようです。

ので、例えば、これがうまく機能している:

[DataContract] 
[KnownType(typeof(int))] 
[KnownType(typeof(double))] 
[KnownType(typeof(string))] 
[KnownType(typeof(Sample))] 
[KnownType(typeof(List<object>))] 
public class Sample 
{ 
    [DataMember] 
    public object[] Values { get; set; } 
} 

と値[i]はint型、ダブル、文字列、自身をサンプルまたは任意の一覧<のいずれかにすることができます>以前のタイプの。

これを発見する前に、私は回避策に取り組んでいましたが、これも機能しますが、コードするのには少し時間がかかります。原則は、 '値'メンバーからDataMember属性を削除し、別のメンバーを追加してシリアル化をコード化することです。

[DataContract] 
public class Sample 
{ 
    public object[] Values { get; set; } 

    [DataMember] 
    public byte[] SerializableValues 
    { 
     get 
     { 
      try 
      { 
       return ToBytes(Values); 
      } 
      catch (Exception e) 
      { 
       return null; 
      } 
     } 

     set 
     { 
      try 
      { 
       Values = FromBytes(value); 
      } 
      catch (Exception e) 
      { 
       Values = null; 
      } 
     } 
    } 
} 
関連する問題