[英]C# Generic Interface with different return types
我有webservice,可以返回多种格式的数据。 例如json和xml。 我正在构建一个简单的C#api来对付这个web服务,我希望这些方法能够从json,raw json或raw xml返回完全序列化的对象。 例如:
List<Order> GetOrders(int customerId)
string GetOrders(int customerId)
XMLDocument GetOrders(customerId)
Customer GetCustomer(int customerId)
string GetCustomer(int customerId)
XMLDocument GetCustomer(int customerId)
我有一个关于做一个流畅的api的想法,你可以调用一个SetFormat()方法,然后返回上述方法的通用接口。 但我仍然坚持该接口的样子,因为返回序列化对象的实现返回不同类型的对象。
另一个更简单的解决方案是只返回返回序列化对象的方法,然后像这样添加一个out参数:
List<Order> GetOrders(int customerId, out string data)
但我认为这不是一个很好的解决方案....
UPDATE
我更喜欢Sjoerd建议的非通用解决方案,我过度复杂了我的问题。 这就是我最终做的事情:
public class ServiceEntity {
List<Order> GetOrders(int customerId)....
}
public class ServiceJson {
string GetOrders(int customerId)....
}
public class ServiceXml {
XmlDocument GetOrders(int customerId)....
}
然后像这样一个流畅的服务类:
public class Service : IService {
....
public AsJson() { return new ServiceJson(); }
public AsEntity() { return new ServiceEntity(); }
public AsXml() { return new ServiceXml(); }
}
像这样使用:
string json = Service.New().AsJson().GetCategories(1);
List<Order> = Service.New().AsEntity().GetCategories(1);
感谢所有的答复!
只需创建一个通用的返回类
public class FormattedClass<T>
{
List<T> ItemList { get; set; }
string Json { get; set; }
XmlDocument Document { get; set; }
}
public FormattedClass<T> GetItems<T>(long primaryKey)
您还可以查看使用隐式运算符按预期返回数据。
例如以下类:
public class OrderThingy
{
public static implicit operator List<Order>(OrderThingy orderthingy)
{
// Use CustomerId to get the data
return new List<Order>();
}
public static implicit operator string(OrderThingy orderthingy)
{
// Use CustomerId to get the data
return "string representation";
}
public static implicit operator XDocument(OrderThingy orderthingy)
{
// Use CustomerId to get the data
return new XDocument();
}
private int CustomerId { get; set; }
public OrderThingy GetOrders(int customerId)
{
CustomerId = customerId;
return this;
}
}
你可以像这样使用它:
XDocument doc = new OrderThingy().GetOrders(1);
List<Order> orders = new OrderThingy().GetOrders(2);
string stringorders = new OrderThingy().GetOrders(2);
尝试使用仿制药很好,但仿制药不是银弹!
在这种情况下,我想知道与非泛型相比你会节省多少代码:
List<Order> GetOrdersAsList(int customerId)
string GetOrdersAsString(int customerId)
XMLDocument GetOrdersAsXml(customerId)
我打赌几乎没有!
如果你决定使用非泛型方法,最有可能最终会在内部结束:
List<Order> GetOrders(int customerId)
string OrdersToString(List<Order> orders)
XMLDocument OrdersToXml(List<Order> orders)
然后可以将后两种方法移动到单独的类中,从而导致GetOrders()
与格式分离。
在我看来,这比在这种情况下尝试使用泛型更好更清洁!
更新 :不要误解我的意思,我喜欢泛型,在很多情况下,它们使代码更具可读性。 其他几个答案非常有趣,因为它们展示了实现这一目标的技术。 所以我建议研究它们:它们可能在其他情况下很有用。 但是在这种情况下 ,到目前为止每个提出的解决方案都有实际缺陷。 这就是我在这种情况下推荐非泛型的原因。
怎么样的方法
private class WebService
{
public T GetOrders<T>(int customerId)
{
if (typeof(T) == typeof(List<Order>))
{
return new List<Order>();
}
if (typeof(T) == typeof(string))
{
return "42";
}
}
}
根据您提供的电话类型,例如:
var webService = new WebService();
var a = webService.GetOrders<List<Order>>();
var b = webService.GetOrders<string>();
你返回预期的价值。
仿制药呢?
T GetOrders<T>(int customerID)
也许将不同的返回类型封装到一个公共类型中:
CustomerResult GetCustomer(int customerId)
哪里
CustomerResults有:
Get/SetFormat()
Get/SetCustomer()
Get/SetXmlDoc()
Get/SetString()
等等
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.