【问题标题】:HOWTO: Pass different types of objects as a parameter to a method depending on the use case scenario如何:根据用例场景将不同类型的对象作为参数传递给方法
【发布时间】:2021-03-14 19:26:15
【问题描述】:

我试图不重复代码,所以我创建了一个参数化的 CreateFile 方法。 它的参数之一 myParams 有时可以是 CustomObject_A 类型,而有时它可以是 CustomObject_B 类型。那么我该如何实现呢?

代码下方:

public class CustomObject_A {
    public DataTable dt { get; set; }
    public string prop1 { get; set; }
}

public class CustomObject_B {
    public List<AnotherCustomObject> lst { get; set; }
    public int prop2 { get; set; }
}

public void DoWork_CreateFile_A(string baseUrl)
{
        string requestUri = "api/MyController/CreateFile_A";
        CustomObject_A myParams = new CustomObject_A();

        this.CreateFile(baseUrl, requestUri, myParams);
}

public void DoWork_CreateFile_B(string baseUrl)
{
        string requestUri = "api/MyController/CreateFile_B";
        CustomObject_B myParams = new CustomObject_B();

        this.CreateFile(baseUrl, requestUri, myParams);
}

public async Task CreateFile(string strBaseUrl, string requestUri, someType myParams)
{        
     using (HttpClient client = new HttpClient())
     {
          client.BaseAddress = new Uri(strBaseUrl);
          client.DefaultRequestHeaders.Clear();
          client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

          string stringMyParams = await Task.Run(() => JsonConvert.SerializeObject(myParams, Newtonsoft.Json.Formatting.Indented,JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }));

          var httpContent = new StringContent(stringMyParams, Encoding.UTF8, "application/json");
          HttpResponseMessage res = await client.PostAsync(requestUri, httpContent);

          if (res.IsSuccessStatusCode)
          {
              // Do things
          }
     }
}

Web API 控制器:

public class MyController : ApiController
{
        public bool CreateFile_A(string data)
        {
              CustomObject_A myData = JsonConvert.DeserializeObject<CustomObject_A>(data);
              // Do some stuff here
        }

        public bool CreateFile_B(string data)
        {
             CustomObject_B myData = JsonConvert.DeserializeObject<CustomObject_B>(data);
             // Do some stuff here
        }
}

【问题讨论】:

  • 由于您没有在CreateFile 中使用myParams 的任何类型特定成员,您可以简单地使用object 作为myParams 的类型

标签: c# asp.net-mvc asp.net-web-api async-await


【解决方案1】:

你所有类似的类都需要继承一个通用接口,然后你可以使用接口作为方法所采用的类型。任何继承该接口的东西都可以传入。

【讨论】:

  • 我认为接口在这里不起作用,因为 CustomObject_A 和 CustomObject_B 没有相同类型的相同对象。
【解决方案2】:

有多种方法可以实现,取决于你想完成什么..

  1. 通用方法

    public async Task CreateFile<T>(string strBaseUrl, string requestUri, T myParams)
     { 
        ....
     }
    
  2. 界面

     public void DoSomething<T>(T param) where T: IFileCreator
     {
        param.CreateFile();
     }
    
     public interface IFileCreator
     {
         void CreateFile();  
     }
    
     public abstract class FileCreatorBase : IFileCreator
     {
         public virtual void CreateFile()
         {
            //common code
         }
     }
    
     public class ClassA : FileCreatorBase
     {
         public int Id { get; set; }
    
         public override void CreateFile()
         {
             Id.Dump();
         }
     }
    
     public class ClassB : FileCreatorBase
     {
         public string Name { get; set; }    
    
         public override void CreateFile()
         {
            Name.Dump();
         }
     }
    
  3. 带虚拟方法的抽象类

         public abstract class FileCreator
         {
             public virtual void CreateFile()
             {
                 //common code
             }
         }
    
         public class ClassA : FileCreator
         {
            public int Id { get; set; }
    
            public override void CreateFile()
            {
               Id.Dump();
            }
         }
    
         public class ClassB : FileCreator
         {
             public string Name { get; set; }
    
             public override void CreateFile()
             {
                 Name.Dump();
             }
         }
    
  4. 带有抽象方法的抽象类

     public abstract class FileCreator
     {
         public abstract void CreateFile();  
     }
    
     public class ClassA : FileCreator
     {
        public int Id { get; set; }
    
        public override void CreateFile()
        {
           Id.Dump();
        }
     }
    
     public class ClassB : FileCreator
     {
         public string Name { get; set; }
    
         public override void CreateFile()
         {
             Name.Dump();
         }
     }
    

【讨论】:

  • 答案对我来说看起来不错,但我开始怀疑这是否是一个家庭作业问题。
猜你喜欢
  • 2022-01-10
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多