C #에서 역 직렬화하는 동안 참조 수정을 수행하는 방법은 무엇입니까?

다른

C # 직렬화 프레임 워크를 사용하여 참조 수정 (사후 처리)을 수행하려면 어떻게해야합니까?

다른 개체를 참조하는 개체가있는 개체 그래프가 있습니다. 그들은 모두 ISerializable인터페이스를 구현하고 모두 인스턴스 ID를 가지고 있으므로 직렬화 된 상태에서 참조를 나타내는 것은 쉽습니다.

krux는 역 직렬화 생성자가 호출 될 때 해당 개체가 참조하는 모든 개체가 역 직렬화되지 않았을 수 있으므로 참조를 유효한 개체로 설정할 수 없다는 것입니다. 그리고 참조 수정을 수행하기 위해 C # 직렬화 프레임 워크의 사후 처리 단계에 연결하는 방법을 찾을 수 없습니다. 그것을 할 방법이 있습니까?


요청에 따라 문제를 강조하는 인위적인 수업이 있습니다.

[Serializable]
public class Pony : ISerializable
{
  public int Id { get; set; }
  public string Name { get; set; }
  public Pony BFF { get; set; }

  public Pony() {}
  private Pony(SerializationInfo info, StreamingContext context) {
    Id = info.GetInt32("id");
    Name = info.GetString("name");
    var bffId = info.GetInt32("BFFId");
    BFF = null; // <===== Fixup! Find Pony instance with id == bffId
  }

  public void GetObjectData(SerializationInfo info, StreamingContext ontext) {
    info.AddValue("id", Id);
    info.AddValue("name", Name);
    info.AddValue("BFFId", BFF.Id);
  }
}

다음은 (비) 직렬화 코드입니다.

var rd = new Pony { Id = 1, Name = "Rainbow Dash" };
var fs = new Pony { Id = 2, Name = "Fluttershy", BFF = rd };
rd.BFF = fs;
var ponies = new List<Pony>{ rd, fs };
Stream stream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(stream, ponies);
stream.Seek(0, SeekOrigin.Begin);
var deserializedPonies = (List<Pony>)formatter.Deserialize(stream);

이 질문은 내 문제를 해결하지 못합니다. .net XML Serialization-Object Copy 대신 참조 저장

BinaryFormatter + ISerializable 프레임 워크를 직렬화에 사용하고 XmlFormater로 전환하지 않고 싶습니다.

Lokusking

이 목적을위한 속성이 있습니다.

역 직렬화하려는 개체에서 다음 메서드를 구현합니다.

[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context) {

}

System.Runtime.Serialization도움이 될 수있는 몇 가지 속성이 더 있습니다.

편집하다

코드를 약간 수정했습니다.

[Serializable]
  public class Pony  {
    public int Id {
      get; set;
    }
    public string Name {
      get; set;
    }
    public Pony BFF {
      get; set;
    }

    public Pony() {
    }

    [OnDeserialized]
    internal void OnDeserializedMethod(StreamingContext context) {
      Console.WriteLine(this.Id + " " + this.Name + " " + this.BFF?.Name);
    }
  }

실험 방법:

var rd = new Pony { Id = 1, Name = "Rainbow Dash" };
      var fs = new Pony { Id = 2, Name = "Fluttershy", BFF = rd };
      rd.BFF = fs;
      var ponies = new List<Pony> { rd, fs };

      object returnValue;
      using (var memoryStream = new MemoryStream()) {
        var binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, ponies);
        memoryStream.Position = 0;
        returnValue = binaryFormatter.Deserialize(memoryStream);
      }
      var xx = (List<Pony>)returnValue;

보시다시피 ISerializableInterface, private contructor 및-Method를 제거했습니다 GetObjectData.

나는 당신이 말하지 않은 것처럼 당신이 정말로 필요하다고 생각하지 않기 때문에 (De) Serialization을 구현했다고 생각합니다.

게시물은 또 다른 정보 소스입니다.

편집 2 (테스트 방법은 동일하게 유지됨) :

접근법 1 (전체 역 직렬화 및 직렬화) ...

    private Pony(SerializationInfo info, StreamingContext context) {

      foreach (SerializationEntry entry in info) {
        switch (entry.Name) {
          case "Id":
            this.Id = (int)entry.Value;
            break;
          case "Name":
            this.Name = (string)entry.Value;
            break;
          case "BFF":
            this.BFF = (Pony)entry.Value;
            break;
        }
      }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext ontext) {
      info.AddValue("Id", Id);
      info.AddValue("Name", Name);
      info.AddValue("BFF", BFF);
    }
  }

...

접근 방식 2 (재귀 객체-ID 만 해당) :

...

private Pony(SerializationInfo info, StreamingContext context) {

      foreach (SerializationEntry entry in info) {
        switch (entry.Name) {
          case "Id":
            this.Id = (int)entry.Value;
            break;
          case "Name":
            this.Name = (string)entry.Value;
            break;
          case "BFF.Id":
            var bffId = (int)entry.Value;
            this.BFF = GetPonyById(bffId); // You have to implement this
            break;
        }
      }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext ontext) {
      info.AddValue("Id", Id);
      info.AddValue("Name", Name);
      info.AddValue("BFF.Id", BFF.Id);
    }

...

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

C #에서 부울 변수에 대한 직렬화 역 직렬화를 수행하는 가장 간단한 방법은 무엇입니까?

분류에서Dev

C #에서 역 직렬화하는 동안 JSON 문자열에없는 속성의 초기화를 방지하는 방법은 무엇입니까?

분류에서Dev

UPW C #의 Web API에서 JSON 배열을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

수식에서 참조 셀을 이동하는 방법은 무엇입니까?

분류에서Dev

수식에서 참조 셀을 이동하는 방법은 무엇입니까?

분류에서Dev

Perl에서 배열을 역 참조하는 방법은 무엇입니까?

분류에서Dev

JSON 문자열을 역 직렬화하는 동안 String.Join을 수행하는 방법은 무엇입니까?

분류에서Dev

JSON 문자열을 역 직렬화하는 동안 String.Join을 수행하는 방법은 무엇입니까?

분류에서Dev

C #을 사용하여 XML 파일에서 데이터를 직렬화 및 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

dart / flutter에서 맵을 올바르게 직렬화 / 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

C ++에서 특수 정렬을 수행하는 방법은 무엇입니까?

분류에서Dev

C #에서 반복 할 수 있도록 JSON 문자열을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

C #에서 반복 할 수 있도록 JSON 문자열을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

JSON을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

둘 이상의 함수에서 전역 변수를 참조하는 방법은 무엇입니까?

분류에서Dev

스칼라 값을 수동으로 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

번역을 참조하는 방법은 무엇입니까?

분류에서Dev

Swift에서 전역 변수를 참조로 업데이트하는 방법은 무엇입니까?

분류에서Dev

.NET에서 참조 비교를 수행하는 방법은 무엇입니까?

분류에서Dev

Java에서 직렬화 및 직렬화 해제 후 참조를 유지하는 방법은 무엇입니까?

분류에서Dev

junit을 수행하는 동안 특정 방법을 조롱하는 방법은 무엇입니까?

분류에서Dev

c에서 구조체 배열을 전역으로 초기화하는 방법은 무엇입니까?

분류에서Dev

전역 명령을 사용하는 동안 vi에서 구문 강조를 활성화하는 방법은 무엇입니까?

분류에서Dev

Boost Graph Library에서 BFS를 진행하는 동안 속성을 수정하는 방법은 무엇입니까?

분류에서Dev

Windows Phone에서 JSON 문자열을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

WCF Restful Service에서 Json 응답을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

Visual Basic 2013에서 Json을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

JavaScriptSerializer. JSON에서 문자열 배열을 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

serde를 사용하여 JSON 배열을 구조체로 역 직렬화하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    C #에서 부울 변수에 대한 직렬화 역 직렬화를 수행하는 가장 간단한 방법은 무엇입니까?

  2. 2

    C #에서 역 직렬화하는 동안 JSON 문자열에없는 속성의 초기화를 방지하는 방법은 무엇입니까?

  3. 3

    UPW C #의 Web API에서 JSON 배열을 역 직렬화하는 방법은 무엇입니까?

  4. 4

    수식에서 참조 셀을 이동하는 방법은 무엇입니까?

  5. 5

    수식에서 참조 셀을 이동하는 방법은 무엇입니까?

  6. 6

    Perl에서 배열을 역 참조하는 방법은 무엇입니까?

  7. 7

    JSON 문자열을 역 직렬화하는 동안 String.Join을 수행하는 방법은 무엇입니까?

  8. 8

    JSON 문자열을 역 직렬화하는 동안 String.Join을 수행하는 방법은 무엇입니까?

  9. 9

    C #을 사용하여 XML 파일에서 데이터를 직렬화 및 역 직렬화하는 방법은 무엇입니까?

  10. 10

    dart / flutter에서 맵을 올바르게 직렬화 / 역 직렬화하는 방법은 무엇입니까?

  11. 11

    C ++에서 특수 정렬을 수행하는 방법은 무엇입니까?

  12. 12

    C #에서 반복 할 수 있도록 JSON 문자열을 역 직렬화하는 방법은 무엇입니까?

  13. 13

    C #에서 반복 할 수 있도록 JSON 문자열을 역 직렬화하는 방법은 무엇입니까?

  14. 14

    JSON을 역 직렬화하는 방법은 무엇입니까?

  15. 15

    둘 이상의 함수에서 전역 변수를 참조하는 방법은 무엇입니까?

  16. 16

    스칼라 값을 수동으로 역 직렬화하는 방법은 무엇입니까?

  17. 17

    번역을 참조하는 방법은 무엇입니까?

  18. 18

    Swift에서 전역 변수를 참조로 업데이트하는 방법은 무엇입니까?

  19. 19

    .NET에서 참조 비교를 수행하는 방법은 무엇입니까?

  20. 20

    Java에서 직렬화 및 직렬화 해제 후 참조를 유지하는 방법은 무엇입니까?

  21. 21

    junit을 수행하는 동안 특정 방법을 조롱하는 방법은 무엇입니까?

  22. 22

    c에서 구조체 배열을 전역으로 초기화하는 방법은 무엇입니까?

  23. 23

    전역 명령을 사용하는 동안 vi에서 구문 강조를 활성화하는 방법은 무엇입니까?

  24. 24

    Boost Graph Library에서 BFS를 진행하는 동안 속성을 수정하는 방법은 무엇입니까?

  25. 25

    Windows Phone에서 JSON 문자열을 역 직렬화하는 방법은 무엇입니까?

  26. 26

    WCF Restful Service에서 Json 응답을 역 직렬화하는 방법은 무엇입니까?

  27. 27

    Visual Basic 2013에서 Json을 역 직렬화하는 방법은 무엇입니까?

  28. 28

    JavaScriptSerializer. JSON에서 문자열 배열을 역 직렬화하는 방법은 무엇입니까?

  29. 29

    serde를 사용하여 JSON 배열을 구조체로 역 직렬화하는 방법은 무엇입니까?

뜨겁다태그

보관