【问题标题】:Using generics in abstract classes在抽象类中使用泛型
【发布时间】:2011-01-22 12:07:42
【问题描述】:

我正在研究一个抽象类,其中实现类需要实现一个 T 列表。问题是这不起作用:

public class AbstractClass
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass
{
    public List<Widgets> Items { get; set; }
}

我确信我缺少一个明显的答案,并且我知道我可以构建一个抽象基类型以放入列表中,但是当我使用我的 Linq 命令来构建列表时,抽象type (ItemBase) 不能很好地与 .ToList() 方法配合使用。我正在尝试做的事情如此独特吗?

【问题讨论】:

  • 原来我需要学习更好的研究。对所有没有得到复选标记的相同答案表示歉意。我根据它的完整性和它是顶级的事实选择了顶级的。
  • 您真的希望Items 是抽象的吗? (即覆盖 get 或 set 属性?)如果您像大多数人建议的那样从 AbstractClass&lt;Widgets&gt; 扩展,Container.Items 将隐含为 List&lt;Widgets&gt;,您甚至不需要覆盖它。
  • 我想保留 getter 和 setter 方法稍后被覆盖的可能性。理论上我不需要,但在实践中试图消除混乱会导致世界受到伤害。

标签: c# generics abstraction


【解决方案1】:

您还需要在类上声明,才能知道T 是什么类型:

public abstract class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass<Widgets>
{
    public override List<Widgets> Items { get; set; }
}

你也可以限制 T 可以是什么,比如说它必须实现 IWidgets:

public class AbstractClass<T> where T : IWidgets

【讨论】:

  • 不要忘记在类声明行本身中添加abstract关键字,而不仅仅是属性。
【解决方案2】:

您需要将AbstractClass 设为通用

public class AbstractClass<T> {
  ...
}

public class Container : AbstractClass<Widgets> { ...
}

【讨论】:

    【解决方案3】:

    需要在抽象类中指定类型:

    public class AbstractClass<T>
    {
        public int Id { get; set; }
        public int Name { get; set; }
    
        public abstract List<T> Items { get; set; }
    }
    
    public class Container : AbstractClass<Widgets>
    {
        public List<Widgets> Items { get; set; }
    }
    

    【讨论】:

      【解决方案4】:

      你需要像这样定义 T

      public class AbstractClass<T>
      {
          public int Id { get; set; }
          public int Name { get; set; }
      
          public abstract List<T> Items { get; set; }
      }
      
      public class Container : AbstractClass<Widget>
      {
          public List<Widgets> Items { get; set; }
      }
      

      【讨论】:

        【解决方案5】:
        • 您需要声明类型 T。
        • 您需要将 AbstractClass 类声明为抽象类。
        • 您需要使用 override 关键字。

        试试这个:

        public class Widgets { }
        
        public abstract class AbstractClass<T>
        {
            public int Id { get; set; }
            public int Name { get; set; }
        
            public abstract List<T> Items { get; set; }
        }
        
        public class Container : AbstractClass<Widgets>
        {
            public override List<Widgets> Items { get; set; }
        }
        

        【讨论】:

          【解决方案6】:
          1. 你需要标记 AbstractClass abstract,因为它包含抽象属性

          2. AbstractClass 声明中指定通用类型

          3. 使用 override

          4. 实现抽象属性
          public abstract class AbstractClass<T> { public int Id { get; set; } public int Name { get; set; } public abstract List<T> Items { get; set; } } public class Container : AbstractClass<Widgets> { public override List<Widgets> Items { get; set; } }

          【讨论】:

            【解决方案7】:

            您缺少为 AbstractClass 类定义抽象关键字,并且您需要为 Container Class Items 属性添加覆盖关键字。我给出的示例代码肯定会运行。

            namespace AbstractGeneric
            {
            
            public abstract class AbstractClass<T>
            {
                public int Id { get; set; }
                public int Name { get; set; }
            
                public abstract List<T> Items { get; set; }
            }
            
            public class Widgets
            {
                public int ID { get; set; }
                public string Name { get; set; }
            }
            
            public class Container : AbstractClass<Widgets>
            {
                public override List<Widgets> Items { get; set; }
                public Container()
                {
                    Items = new List<Widgets>();
                }
            
            }
            
            
            class Program
            {
                static void Main(string[] args)
                {
                    Container c = new Container();
                    c.Items.Add(new Widgets() { ID = 1, Name = "Sample Widget 1" });
                    c.Items.Add(new Widgets() { ID = 2, Name = "Sample Widget 2" });
            
                    foreach (Widgets item in c.Items)
                    {
                        Console.WriteLine(item.ID + " : " + item.Name);
                    }
            
                    Console.ReadLine();
                }
            }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-11-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-05-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多