2

質問があります。

以下を考慮してください

IService1.cs

[ServiceContract]
public interface IService1
{


    [OperationContract]
    Hashtable GetHashTableCollection();


    [OperationContract]
    List<A> GetARecords();


}

[DataContract]
public class A
{
    [DataMember]
    public int MyProperty { get; set; }

    [DataMember]
    public Hashtable MyTable { get; set; }
}

Service1.cs

    public class Service1 : IService1
    {
        public Hashtable GetHashTableCollection()
        {
            Hashtable hashtable = new Hashtable();
            hashtable.Add("Area", 1000);
            hashtable.Add("Perimeter", 55);
            hashtable.Add("Mortgage", 540);
            return hashtable;
        }

        public List<A> GetARecords()
        {
            List<A> Alist = new List<A>();
            Alist.Add(new A { MyProperty = 1, MyTable = GetHashTableCollection() });
            Alist.Add(new A { MyProperty = 2, MyTable = GetHashTableCollection() });

            return Alist;
        }
  }

そして、クライアントアプリケーションは以下の通りです

private void button1_Click(object sender, EventArgs e)
{
   ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
   var r1 = sc.GetHashTableCollection(); 
   var r2 = sc.GetARecords();
}

問題なく動作しています。HashTableはDictionaryオブジェクトに変換されました。

HashTableはIDictionaryを使用しているので、コンパイル時に失敗するはずだという印象を受けました(3.5で発生)。

タイプ「System.Collections.Generic.Dictionary」を「System.Collections.Hashtable」に暗黙的に変換することはできません

しかし、それはうまくいきました。どのように?

基本的なコンセプトが欠けていますか?またはDataContractSerializerが作業を行っていますか?または、dot.net 4.0で何かが変更されましたか?

それは何であり、なぜそれが機能しているのですか?

4

1 に答える 1

1

に基づいていIDictionaryます。WCFはIDictionaryをとして扱いDictionary<object, object>、WSDLでそのように公開されます。を実装したカスタムクラスを持つことができIDictionary、動作は同じになります。たとえば、以下のプロジェクトのいずれかを実行し、svcutilまたはサービス参照の追加を使用して、IDictionaryタイプがあったサービスへのプロキシを生成するとDictionary<object, object>、代わりにクライアントでを取得します。

public class StackOverflow_15471185
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        Hashtable GetHashTableCollection();
        [OperationContract]
        List<A> GetARecords();
    }

    [DataContract]
    public class A
    {
        [DataMember]
        public int MyProperty { get; set; }

        [DataMember]
        public Hashtable MyTable { get; set; }
    }

    public class Service : IService1
    {
        public Hashtable GetHashTableCollection()
        {
            Hashtable hashtable = new Hashtable();
            hashtable.Add("Area", 1000);
            hashtable.Add("Perimeter", 55);
            hashtable.Add("Mortgage", 540);
            return hashtable;

        }

        public List<A> GetARecords()
        {
            List<A> Alist = new List<A>();
            Alist.Add(new A { MyProperty = 1, MyTable = GetHashTableCollection() });
            Alist.Add(new A { MyProperty = 2, MyTable = GetHashTableCollection() });

            return Alist;
        }
    }

    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "");
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.Open();
        Console.WriteLine("Host opened");

        var factory = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
        var proxy = factory.CreateChannel();
        Console.WriteLine(proxy.GetHashTableCollection());

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

public class StackOverflow_15471185_b
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        MyDic GetHashTableCollection();
        [OperationContract]
        List<A> GetARecords();
    }

    public class MyDic : IDictionary
    {
        public IDictionary dic = new Hashtable();

        public void Add(object key, object value)
        {
            dic.Add(key, value);
        }

        public void Clear()
        {
            dic.Clear();
        }

        public bool Contains(object key)
        {
            return dic.Contains(key);
        }

        public IDictionaryEnumerator GetEnumerator()
        {
            return dic.GetEnumerator();
        }

        public bool IsFixedSize
        {
            get { return dic.IsFixedSize; }
        }

        public bool IsReadOnly
        {
            get { return dic.IsReadOnly; }
        }

        public ICollection Keys
        {
            get { return dic.Keys; }
        }

        public void Remove(object key)
        {
            dic.Remove(key);
        }

        public ICollection Values
        {
            get { return dic.Values; }
        }

        public object this[object key]
        {
            get
            {
                return dic[key];
            }
            set
            {
                dic[key] = value;
            }
        }

        public void CopyTo(Array array, int index)
        {
            dic.CopyTo(array, index);
        }

        public int Count
        {
            get { return dic.Count; }
        }

        public bool IsSynchronized
        {
            get { return dic.IsSynchronized; }
        }

        public object SyncRoot
        {
            get { return dic.SyncRoot; }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)dic).GetEnumerator();
        }
    }

    [DataContract]
    public class A
    {
        [DataMember]
        public int MyProperty { get; set; }

        [DataMember]
        public MyDic MyTable { get; set; }
    }

    public class Service : IService1
    {
        public MyDic GetHashTableCollection()
        {
            MyDic hashtable = new MyDic();
            hashtable.Add("Area", 1000);
            hashtable.Add("Perimeter", 55);
            hashtable.Add("Mortgage", 540);
            return hashtable;

        }

        public List<A> GetARecords()
        {
            List<A> Alist = new List<A>();
            Alist.Add(new A { MyProperty = 1, MyTable = GetHashTableCollection() });
            Alist.Add(new A { MyProperty = 2, MyTable = GetHashTableCollection() });

            return Alist;
        }
    }

    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "");
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.Open();
        Console.WriteLine("Host opened");

        var factory = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
        var proxy = factory.CreateChannel();
        Console.WriteLine(proxy.GetHashTableCollection());

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
于 2013-03-18T23:44:24.783 に答える