簡體   English   中英

具有不同返回類型的C#通用接口

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM