c#REST API多态返回类型

时间:2017-07-12 11:13:44

标签: c# inheritance asp.net-web-api polymorphism response

我已经创建了具有继承的数据合同: -

[DataContract(Name = "Animal")]
public class Animal { ... }

[DataContract(Name = "Dog ")]
public class Dog : Animal { // Has some Dog specific member properties }

[DataContract(Name = "Cat ")]
public class Cat : Animal { // Has some Cat specific member properties }

我正在使用ASP.NET WebApi来提供如下的REST API:

[HttpGet]
public Task<Animal> Get(string type) 
{ 
    switch(type)
    {
        case "dog":
            Dog dog = GetDogDetails();
            return Task.FromResult(dog);
            break;

        case "cat":
            Cat cat = GetCatDetails();
            return Task.FromResult(cat);
            break:
    }
}

我无法归还各自的动物类型。我收到以下错误: - “不能隐含地将狗转变为动物”。

根据REST API标准,这种多态响应也是一件好事。

1 个答案:

答案 0 :(得分:6)

您收到此错误的原因是您返回Task<T>且任务不协变。也就是说,即使DogAnimalTask<Dog>也不是Task<Animal>

你能做什么?

  1. 将您的代码更改为

        case "dog":
        Animal dog = GetDogDetails();
        return Task.FromResult(dog);
        break;
    
  2. 但是你会失去狗的特定属性。

    1. 利用Task<IHttpActionResult>并返回Ok(yourObject)

      [HttpGet]
      public async Task<IHttpActionResult> Get(string type) 
      { 
          switch(type)
          {
              case "dog":
                  Dog dog = GetDogDetails();
                  return Ok(dog);
                  break;
      
          ...
          }
      }
      
    2. 我认为你应该采取第二种方式。

      在第二个注释中,我真的没有理由在这里使用async/await。你为什么要用Task.FromResult?如果您的GetDogDetails方法为async,请考虑awaiting。我认为您不应该担心当前代码中的任务。

        

      根据REST API标准,这种多态响应也是一件好事。

      我不了解正式标准,但一般情况下,某些对象可以拥有某些属性而其他对象则无法使用。例如,假设一个支付系统返回一个抽象事件,该事件可能有也可能没有相关的发票。