3

クリップボードからコピーしようとしている[Serializable]とマークしたクラスがあります。GetData()を呼び出すと、常にnullが返されます。

コピーコード:

IDataObject dataObject = new DataObject();
dataObject.SetData("MyClass", false, myObject);
Clipboard.SetDataObject(dataObject, true);

コードを貼り付けます:

if (Clipboard.ContainsData("MyClass"))
{
    IDataObject dataObject = Clipboard.GetDataObject();

    if (dataObject.GetDataPresent("MyClass"))
    {
        MyClass myObject = (MyClass)dataObject.GetData("MyClass");
        // myObject is null
    }
}

MyClassは、実際には派生クラスです。それとそのベースの両方に[Serializable]のフラグが付けられます。簡単なテストクラスで同じコードを試しましたが、うまくいきました。

MyClassには、GraphicsPath、Pen、Brush、および値型の配列が含まれています。

4

2 に答える 2

3

Penクラスはシリアル化可能としてマークされておらず、MarshalByRefObjectからも継承されます。

ISerializableを実装し、これらのタイプのオブジェクトを処理する必要があります

[Serializable]
public class MyClass : ISerializable
{
    public Pen Pen;

    public MyClass()
    {
        this.Pen = new Pen(Brushes.Azure);
    }

    #region ISerializable Implemention

    private const string ColorField = "ColorField";

    private MyClass(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");

        SerializationInfoEnumerator enumerator = info.GetEnumerator();
        bool foundColor = false;
        Color serializedColor = default(Color);

        while (enumerator.MoveNext())
        {
            switch (enumerator.Name)
            {
                case ColorField:
                    foundColor = true;
                    serializedColor = (Color) enumerator.Value;
                    break;

                default:
                    // Ignore anything else... forwards compatibility
                    break;
            }
        }

        if (!foundColor)
            throw new SerializationException("Missing Color serializable member");

        this.Pen = new Pen(serializedColor);
    }

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(ColorField, this.Pen.Color);
    }
    #endregion
}
于 2012-03-08T21:09:55.483 に答える
1

私は同じ問題を抱えていたので、このリンクをグーグルで見つけました。これにより、クラスのどの部分がシリアル化できないかをテストするための関数IsSerializableが提供されます。この関数を使用することにより、それらの部分が[Serializable]を使用してシリアル化可能になっていることがわかりました。シリアル化されるクラスが使用するモジュール(一般など)内で定義されたすべての構造体とクラスは、[Serializable]としてマークする必要があることに注意してください。コードの一部はシリアル化できない/シリアル化しないでください。また、[NonSerialized]として明確にマークする必要があります。例:System.Data.OleDBConnection

于 2013-03-16T22:48:05.413 に答える