5

Basically, should the code below work and serialize string Yoyo when an object of type YoyoData is returned over the wire.

    public interface IHelloV1
    {
        #region Instance Properties

        [DataMember(Name = "Yoyo")]
        string Yoyo { get; set; }

        #endregion
    }


    [DataContract(Name = "YoyoData", Namespace = "http://hello.com/1/IHelloV1")]
    public class YoyoData : IHelloV1
    {
        string Yoyo { get; set; }

        public YoyoData()
        {
            Yoyo = "whatever";
        }
    }
}
Matt
  • 25,943
  • 66
  • 198
  • 303

2 Answers2

6

I don't think it will.

The DataMember attribute is not inherited in derived classes.

For more details see documentation of type DataMemberAttribute and how it is defined : http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx. This attribute specifies the property Inherited = false meaning the attribute won't be propagated to derived classes.

Also see http://msdn.microsoft.com/en-us/library/84c42s56(v=vs.71).aspx for more details concerning the Inherited property on attributes.

Anyway, this means that in your class defining the DataContract, the property Yoyo won't be considered a DataMember so for me it will just not work as expected.

darkey
  • 3,672
  • 3
  • 29
  • 50
  • My testing confirms this. I was just curious if I had missed a step, but what you said makes sense. Thanks! – Matt Aug 01 '12 at 22:36
3

It would appear that it does not work:

using System.Runtime.Serialization;
using System.IO;
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            IHelloV1 yoyoData = new YoyoData();
            var serializer = new DataContractSerializer(typeof(YoyoData));

            byte[] bytes;
            using (var stream = new MemoryStream())
            {
                serializer.WriteObject(stream, yoyoData);
                stream.Flush();
                bytes = stream.ToArray();
            }

            IHelloV1 deserialized;
            using (var stream = new MemoryStream(bytes))
            {
                deserialized = serializer.ReadObject(stream) as IHelloV1;
            }

            if (deserialized != null && deserialized.Yoyo == yoyoData.Yoyo)
            {
                Console.WriteLine("It works.");
            }
            else
            {
                Console.WriteLine("It doesn't work.");
            }

            Console.ReadKey();
        }
    }

    public interface IHelloV1
    {
        #region Instance Properties

        [DataMember(Name = "Yoyo")]
        string Yoyo { get; set; }

        #endregion
    }


    [DataContract(Name = "YoyoData", Namespace = "http://hello.com/1/IHelloV1")]
    public class YoyoData : IHelloV1
    {
        public string Yoyo { get; set; }

        public YoyoData()
        {
            Yoyo = "whatever";
        }
    }
}

BUT, if you throw that attribute on the class property instead of the interface property, it does work.

Dan
  • 9,717
  • 4
  • 47
  • 65