문제

객체를 직렬화하는 문제가 있었고 문제를 특정 사례로 좁혔습니다 (아래 코드 참조). 다음과 같은 오류가 발생했습니다.

오류 1 유효하지 않은 Resx 파일. serialisation.harness.blob, serialization, version = 1.0.0.0, culture = neutral, publicKeyToken = null을로드 할 수 없습니다. .Resx 파일에 사용됩니다. 필요한 참조가 프로젝트에 추가되었는지 확인하십시오. 라인 129, 위치 5. ... ...

이제 정말 이상한 점은 Visual Studio를 다시 시작하면 오류가 사라지고 코드가 작동하지만 겉보기에는 임의의 빌드를 한 후에 (그 동안 상기 코드가 ~ 아니다 변경) 다시 파손됩니다.

내가 뭘 잘못하고/놓치고 있는지 볼 수 있습니까?

미리 감사드립니다.

메토

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design; using System.ComponentModel.Design;

namespace Serialisation.Harness
{    

    [Serializable]
    public class Blob
    {
        public Blob()
        {
        }
    }

    [Serializable]
    public class Basic
    {

        private List<Blob> blobs;
        public List<Blob> Blobs
        {
            get { return blobs; }
            set { this.blobs= value; }
        }

        public Basic()
        {
            basics = new List<Blob>();
        }

    }

    public class BasicComponent : Component
    {

        private Basic basic = new Basic();

        private IContainer components = new Container();

        public List<Blob> Blobs
        {
            get { return basic.Blobs; }
            set { basic.Blobs= value; }
        }

        public BasicComponent(IContainer container)
        {
            container.Add(this);
        }

    }

}
도움이 되었습니까?

해결책

우선, Serializable 속성은 디자이너 직렬화에 사용되지 않습니다. 객체를 직렬화 할 때 디자이너는 디자이너 코드에 작성하는 방법을 모르면 리소스 파일로 직렬화됩니다. 이것은 그것을 InstanceDescriptor 객체 유형의 기본 생성자의 경우 (포함 할 속성 값도 손실됩니다). 이것이 일어나고있는 일입니다 Blobs 디자이너가 일반 목록을 멋지게 직렬화하지 않기 때문에 속성 (배열을 직렬화하는 방법을 알고 있습니다).

이러한 지속적인 객체 내부에 정보를 유지하려면 TypeConverter 이는 다른 생성자를 지정합니다 InstanceDescriptor (실제로 당신과 같은 속성을 설명하기 위해 실제로 어떤 상태를 취하는 Blobs 재산). 예를 들어, 생성자를 추가 한 경우 BasicComponent 사용하는 유형 IEnumerable<Blob>, 당신은 얻을 수 있습니다 InstanceDescriptor 해당 생성자에게 배열을 통과합니다 Blobs (새로운 것을 만들 것입니다 List<Blob> 생성자에서 그 주위). 디자이너는 지속되는 방법을 알고 있기 때문입니다 InstanceDescriptor 코드를 코딩하고 코드에 배열을 지속하는 방법을 알고 있으므로 RESX 대신 디자이너 코드에 추가됩니다.

당신은 또한 구현할 수 있습니다 CodeDomSerializer 인스턴스를 설명하는 데 사용되는 코드를 지정하려면 디자이너가 객체를 RESX 대신 디자이너 코드에 저장하는 데 사용할 수있는 코드를 지정합니다.

변환기 유형

유형 변환기 접근 방식을 사용하려면 다음과 같은 작업을 수행 할 수 있습니다.

public class BasicComponentTypeConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        bool canConvert = base.CanConvertTo(context, destinationType);

        if (!canConvert &&
            (destinationType == typeof(InstanceDescriptor))
        {
            canConvert = true;
        }

        return canConvert;
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        object conversion = null;

        if (culture == null)
        {
            culture = CultureInfo.CurrentCulture;
        }

        BasicComponent component = value as BasicComponent;
        if (basicComponent != null)
        {
            if (destinationType == typeof(InstanceDescriptor))
            {
               // Note that we convert the blobs to an array as this makes for nicer persisted code output.
               // Without it, we might just get a resource blob which is not human-readable.
               conversion = new InstanceDescriptor(
                   typeof(BasicComponent).GetConstructor(new Type[] { typeof(IEnumerable<Blob>) }),
                   new object[] { basicComponent.Blobs.ToArray() },
                   true);
            }
        }

        if (conversion == null)
        {
            conversion = base.ConvertTo(context, culture, value, destinationType);
        }

        return conversion;
    }
}

유형 변환기를 작성해야 할 수도 있습니다. Blob 또한 입력하십시오. 유형 변환기를 유형에 부착하려면 TypeConverter 속성 클래스에서 유형 변환기가 변환됩니다. 즉, 위의 예제는 기본 콘버터입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top