【问题标题】:Is it possible to define a list of anytype in class which can hold list of any type是否可以在可以保存任何类型列表的类中定义任何类型的列表
【发布时间】:2018-07-05 12:28:30
【问题描述】:
public class DataTableRequest
{
    public int draw { get; set; }
    public int start { get; set; }
    public int length { get; set; }
    public List<Column> columns { get; set; }
    public Search search { get; set; }
    public List<Species> data { get; set; }/*here I want to hold list of any type */
    public int recordsTotal { get; set; }
}

上面是模型,有属性列表数据,我想在其中保存两个模型下面的数据。我不想在化学品的 DataTableRequest 中创建另一个列表属性。我想要一种方法来创建一个可以保存两种模型列表的属性。

public partial class Species
{
    public int SpeciesId { get; set; }
    public string SpeciesName { get; set; }
    public string FileName { get; set; }
    public bool IsActive { get; set; }
}

public partial class Chemical
{
    public int ChemicalId { get; set; }
    public string ChemicalName { get; set; }
    public string FileName { get; set; }
    public bool IsActive { get; set; }
}

有没有定义一个可以同时包含化学和物种列表的列表?

【问题讨论】:

  • List&lt;object&gt;?
  • DataTableRequest 的单个实例是否有一个包含SpeciesChemical 实例的混合列表,还是每个实例仅包含一个或另一个?
  • Damien_The_Unbeliever 每个实例只包含一个或另一个。

标签: c# .net generics


【解决方案1】:

是的,一种方法是添加一个基类并从它继承。

例子:

先添加基类...

class BaseClass
{}

class Species : BaseClass
{...}

class Chemical : BaseClass
{...}

...然后将您的列表定义为

public List<BaseClass> data { get; set; } 

【讨论】:

    【解决方案2】:

    使用泛型

    void Main()
    {
        var speciesDataTableRequest = new DataTableRequest<Species>();
        var chemicalsDataTableRequest = new DataTableRequest<Chemical>();
    }
    
    // Define other methods and classes here
    public class DataTableRequest<T>
    {
        public int draw { get; set; }
        public int start { get; set; }
        public int length { get; set; }    
        public List<T> data { get; set; }/*any type now*/
        public int recordsTotal { get; set; }
    }
    
    public partial class Species
    {
        public int SpeciesId { get; set; }
        public string SpeciesName { get; set; }
        public string FileName { get; set; }
        public bool IsActive { get; set; }
    }
    
    public partial class Chemical
    {
        public int ChemicalId { get; set; }
        public string ChemicalName { get; set; }
        public string FileName { get; set; }
        public bool IsActive { get; set; }
    }
    

    【讨论】:

    • 这将是最好的方法。谢谢阿德里安
    【解决方案3】:

    您不能为此目的使用泛型,但您可以根据类的结构引入类的通用接口

    public interface IData
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string FileName { get; set; }
        public bool IsActive { get; set; }
    }
    
    public class Species :IData {}
    
    public class Chemical :IData {}
    

    前缀“SpeciesId”和“ChemicalId”是多余的,因为类的名称将代表所需的信息。

    【讨论】:

      【解决方案4】:

      有两种方法可以实现。

      1. 将您的data 属性定义为List&lt;object&gt; 或只是ArrayList,它本质上还是一个对象列表。 使用这种方法,每次您需要根据对象的类型进行查找时,您都必须使用 is 运算符检查对象的实际类型。

      2. 第二种选择是按照@ViRuSTRiNiTy 所说的去做 - 引入一个人工基类,但查找需要遵循与第一种情况类似的模式。您还可以在此处使用标记界面(没有任何成员的界面)。但同样,您将从这种方法中获得的唯一好处是您将使用泛型并减少可以存储在 data 属性中的对象类型。

      如果您能够更改DataTableRequest 类型,最好为两种不同类型添加两个单独的通用列表。或者,如果这不是一个选项,只需将过滤器属性添加到 DataTableRequest,如下所示:

      public class DataTableRequest
      {
          // the list of existing properties here
          public List<object> Data {get; set;}
      
          public IEnumerable<Species> Species
          {
              get { return this.Data.OfType<Species>(); }
          }
      
          public IEnumerable<Chemical> Chemicals
          {
              get { return this.Data.OfType<Chemical>(); }
          }
      }
      

      如果您需要,这些将有助于迭代特定类型的对象。当然,如果你没有这样的场景,你不应该添加这些属性。

      【讨论】:

      【解决方案5】:

      您可以通过最少的代码更改来实现它,例如 -

      只需添加一个接口并包含您的类列表(可以扩展以防添加新类

      public interface IListOfAnything
          {
              List<Species> ListOfSpecies { get; set; }
              List<Chemical> ListOfChemical { get; set; }
              // List<SomeNewitem> ListOfSomeNewitem { get; set; }
          }
      
      public class DataTableRequest
      {
          public int draw { get; set; }
          public int start { get; set; }
          public int length { get; set; }
          public List<Column> columns { get; set; }
          public Search search { get; set; }
          public IListOfAnything data { get; set; }/*here you get list both type of model */
          public int recordsTotal { get; set; }
      }
      

      你的 Main() 看起来像这样 -

      static void Main(string[] args)
      {
           DataTableRequest dtr = new DataTableRequest();
           dtr.data.ListOfChemical = new List<Chemical>();
           dtr.data.ListOfSpecies = new List<Species>();
           // dtr.data.ListOfSomeNewitem = new List<SomeNewitem>();
      }
      

      这样您当前的代码结构将尽可能地保留。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 2016-05-06
        相关资源
        最近更新 更多