WCF。 IList被反序列化为数组。 如何使它成为任何可写列表(ArrayList)?

我有一个客户端 – 服务器应用程序,其中一部分通过WCF(netTcp绑定)相互“交谈”。

我有我的DataContract,它有一个第三方类的字段:

[Serializable] public class MyResult{ public ThirdPartyResult Result {get;set;} /* other fields */ } 

使用reflection我看到这个:

 [Serializable] public class ThirdPartyResult { private IList result; public IList Result { get { return result ?? (result = new ArrayList());} } } 

从客户端调用服务器时,我将result作为服务器上的ArrayList 。 在客户端之后, result字段变为固定大小的数组。

没有使用添加服务引用 ,但我使用程序集共享,只是这样做

 ChannelFactory.CreateChannel(new NetTcpBinding("Configuration.Name"), address); 

更新:服务合同

 [ServiceContract] [ServiceKnownType(typeof(ArrayList))] [ServiceKnownType(typeof(ThirdPartyResult))] public interface IMyContract { MyResult GetResult(); } 

现在的问题是:
如何告诉WCF使用ArrayList而不是Array


我提出了一个非常糟糕的解决方案(从我的角度来看)
通常我希望保留一个ArrayList以便能够向其添加项目。 最后我想出了下面的解决方案。 是的,我知道,这是完全糟糕的,这就是为什么我还在寻找更好的变体。

  if (thirdParty.Results != null && thirdParty.Results.IsFixedSize) { var results = new ArrayList(thirdParty.Results); // Finding result by ReferenceEquals to not be tight to private variable name var resultsField = thirdParty.GetType() .GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic) .Where(f => ReferenceEquals(f.GetValue(thirdParty), thirdParty.Results)) .FirstOrDefault(); if (resultsField != null) resultsField.SetValue(thirdParty, results); } thirdParty.AddResult(otherChild); 

在Visual Studio中创建新的服务引用(或配置现有引用)时,有一个类似“将数组反序列化”的属性,您可以在其中选择数组/列表/等。 您可以查看生成的代码并更改代码以实现您想要的。

请参阅以下内容:

WCF:序列化和反序列化通用集合

这解决了我的问题:私有成员和自定义属性方法都适合我。

 [DataMember] private List members = new List(); 

或者将属性更改为:

 [DataMember] private Iist members = new Iist(); [DataMember()] public IList Feedback { get { return m_Feedback; } set { if ((value != null)) { m_Feedback = new List(value); } else { m_Feedback = new List(); } } } 

最终,您的合同中不包含任何可以选择任何特定实施的信息。 解决这个问题的最佳方法是: 使result良好,也许作为ArrayList

 private ArrayList result; public IList Result { get { return result ?? (result = new ArrayList());} } 

个人希望看到带有[DataContract] / [DataMember]等的List ,但……

如果没有别的,那么我会写一个扩展类来扩展ThirdPartyResult

  public static class ThirdPartyResultExtension { public static ArrayList ResultsAsArrayList(this ThirdPartyResult d) { ArrayList list = new ArrayList(); list.AddRange(d.Result); return list; } } public class ThirdPartyResult { private IList result; public IList Result { get { return result ?? (result = new ArrayList()); } } } 

并使用它

  ThirdPartyResult r; ArrayList arrlist = r.ResultsAsArrayList();