答案 0 :(得分:12)
如果您真的想要,可以在服务合约定义中使用接口,只要您按照自己的方式包含已知类型(稍作调整,请参见下文)。
显然,使用接口作为泛型类型参数使其成为C#3.0的桥梁。我将已知的类型属性更改为
[ServiceKnownType(typeof(Batch<Command>))]
public interface IActions
{
}
这使得它在某种程度上起作用。序列化和反序列化本身也可以,但是你遇到了这个例外:
无法转换'Batch`1 [Command]'类型的对象 输入'IBatch`1 [ICommand]'。
要使该转换工作,您需要语言支持泛型类型协方差,这是C#4.0中引入的。但是要在C#4.0中工作,你需要添加一个方差修饰符:
public interface IBatch<out T>
{
}
然后它完美地工作......不幸的是你没有使用C#4.0。
在服务合同中使用接口的最后一件事:如果您从它们生成服务引用,它将所有接口参数键入为object
,因为原始接口类型不是元数据。您可以通过程序集引用共享契约,或手动重构生成的代理来修复它,但总而言之,使用WCF的接口可能比它的价值更麻烦。
答案 1 :(得分:2)
答案 2 :(得分:1)
答案 3 :(得分:1)
泛型可以序列化,但有一定的局限性。例如,给定数据合同:
[DataContract]
public class Foo<T>
{
[DataMember]
public T Value { get; set; }
}
服务合同:
[ServiceContract]
public interface IService1
{
[OperationContract]
Foo<String> GetData();
}
服务实施:
public class Service1 : IService1
{
public Foo<string> GetData()
{
return new Foo<string>() { Value = "My test string" };
}
}
在为上述服务设置服务参考后,可以运行以下代码:
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
ServiceReference1.FooOfstring temp = client.GetData();
MessageBox.Show(temp.Value);
显示带有“我的测试字符串”的消息框。
请注意,服务本身不是通用的,但使用的数据合同是。此外,在客户端生成的数据协定不是通用的,而是具有类型为string的属性值的“扁平”类:
[System.Runtime.Serialization.DataMemberAttribute()]
public string Value
{
get {...}
set {...}
}