【问题标题】:You can mix derived and base classes in a generic list in C# of type base class?您可以在 C# 类型基类的泛型列表中混合派生类和基类吗?
【发布时间】:2012-07-26 09:04:40
【问题描述】:

您可以在 C# 中基类类型的泛型列表中混合派生类和基类吗?我不明白为什么不...而且我没有看到一个明确的答案...但是今天玩了一个类型基类的通用列表,其中也有派生类,我没有看到任何问题。但我想知道是否可能存在潜在问题,除了派生/基类中总是固有的通常的向上/向下转换限制。我问的原因是:我不知道 C# 的通用列表是否与 C++ 中过去称为 ArrayList 的工作方式相同,也就是说,在编译过程中你是否会因为像这样混合“类型”而受到任何抱怨(基类与派生类)。我今天运行了许多示例而没有抱怨,但想验证是否存在问题的可能性。

【问题讨论】:

  • 那么你是怎么做的,你有没有在派生类中添加任何其他东西,或者它只是具有不同名称的基类?你能举出你的例子吗?
  • 与 java 和 c++ 相比,为了更好地理解 c# 中的泛型类,您可以查看SO question。

标签: c# list generics derived-types


【解决方案1】:

C# 类类型是引用类型。 C++ 类类型在 .NET 世界中称为值类型。适当的比较是基类指针的 C++ 列表,您可以在其中存储指向派生类的指针而不会出现任何问题。

是的,没关系。

【讨论】:

    【解决方案2】:
     using System;
     using System.Collections.Generic;
    
     namespace DoFactory.GangOfFour.Composite.Structural
    {
    /// <summary>
    /// MainApp startup class for Structural 
    /// Composite Design Pattern.  
    /// </summary>
    class MainApp
    {
        /// <summary>
        /// Entry point into console application.
        /// </summary>
        static void Main()
        {
            // Create a tree structure
            Composite root = new Composite("root");
            root.Add(new Leaf("Leaf A")); //1st Add for root
            root.Add(new Leaf("Leaf B")); //2nd Add for root
            Console.WriteLine(" ....");
            root.Display(1);
            Console.WriteLine("...........");
            Composite comp = new Composite("Composite X");
            comp.Add(new Leaf("Leaf XA"));
            root.Add(comp); //add comp to root //3rd Add for root
    
            DerivedComposite myDerivedComposite = new DerivedComposite("derived member",      1000);
            Console.WriteLine("Show the special int, string for DerivedComposite");
            myDerivedComposite.mySpecialVariablesAre();
            Console.WriteLine("........");
    
            root.Add(myDerivedComposite); //4th Add for root
    
            Composite SecondRoot = new Composite("SecondRoot");
            SecondRoot.Add(new Leaf("Leaf fA"));
    
    
            SecondRoot.Add(myDerivedComposite); //add to SecondRoot
    
            root.Add(SecondRoot); //add comp to root ; //5th Add for root
            //// Recursively display tree again, after adding
            root.Display(1);
    
            Console.WriteLine("Now get List read back");
            Console.WriteLine("show List elements for root (should be five)");
            root.DisplayList();
    
            Console.WriteLine("Show List elements for comp (should be one)");
            comp.DisplayList();
            Console.WriteLine("Show List ele for SecondRoot (should be 2)");
             SecondRoot.DisplayList();
    
            // Wait for user
            Console.ReadKey();
        }
    }
    
    
    /// <summary>
    /// The 'Component' abstract class
    /// </summary>
    abstract class Component
    {
        protected string name;
    
        // Constructor
        public Component(string name)
        {
            this.name = name;
        }
    
        public abstract void Add(Component c);
        public abstract void Remove(Component c);
        public abstract void Display(int depth);
        public abstract void printSpecialInt();
    }
    
    /// <summary>
    /// The 'Composite' class
    /// </summary>
    class Composite : Component
    {
        private List<Component> _children = new List<Component>(); 
        //This Generic List was potentially troublesome but it executed fine
        protected int specialbaseInt;
        // Constructor
        public Composite(string name)
            : base(name)
        {
            specialbaseInt = -1;
        }
    
        public override void Add(Component component)
        {
            _children.Add(component);
        }
    
        public override void Remove(Component component)
        {
            _children.Remove(component);
        }
    
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-', depth) + name);
    
            // Recursively display child nodes
            foreach (Component component in _children)
            {
                component.Display(depth + 2); //calls .Display again, is recursive
            }
        }
    
        public void DisplayList()
        {
            int ijk = _children.Count;
            Console.WriteLine("# elements in this List: {0}", ijk);
            foreach (Component c in _children)
            {
                int ii = c.GetHashCode();
                Type type = c.GetType();
                Console.WriteLine("GetHashCode, Type on list: {0}, {1}", ii, type.FullName);
    
                c.printSpecialInt();
    
            }
        }
    
        public override void printSpecialInt()
        {
            Console.WriteLine("special int (at base class): {0}", specialbaseInt);
        }
    }
    
    class DerivedComposite : Composite
    {
        public string myExtraString;
        public int mySpecialInt;
    
        public DerivedComposite(string name,int ianint)
            : base(name)
        {
            myExtraString = name;
            mySpecialInt = ianint + 10;
            specialbaseInt = ianint;
        }
    
        public void mySpecialVariablesAre()
        {
            Console.WriteLine("The string, int, specialbaseInt are!- {0}, {1}, {2}", myExtraString, mySpecialInt, specialbaseInt);
        }
    
        public override void printSpecialInt()
        {
            Console.WriteLine("The string, int, specialbaseInt are (at derived): {0}, {1},    {2}", myExtraString, mySpecialInt, specialbaseInt);
        }
    
    }
    
    /// <summary>
    /// The 'Leaf' class
    /// </summary>
    class Leaf : Component
    {
        // Constructor
        public Leaf(string name)
            : base(name)
        {
        }
    
        public override void Add(Component c)
        {
            Console.WriteLine("Cannot add to a leaf");
        }
    
        public override void Remove(Component c)
        {
            Console.WriteLine("Cannot remove from a leaf");
        }
    
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-', depth) + name);
        }
    
        public override void printSpecialInt()
        {
            Console.WriteLine("at Leaf printSpecialInt");
        }
    }
    
    /// <summary>
    /// The 'Leafail' class //try and make it fail
    /// </summary>
    class Leafail : Component
    {
        // Constructor
        public Leafail(string name)
            : base(name)
        {
            myExtraString = "Hi, I am Leafail";
            mySpecialInt = 123;
        }
    
        public string myExtraString;
        public int mySpecialInt;
    
        public override void Add(Component c)
        {
            Console.WriteLine("Cannot add to a leafail");
        }
    
        public override void Remove(Component c)
        {
            Console.WriteLine("Cannot remove from a leafail");
        }
    
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-', depth) + name);
        }
    
        public void mySpecialVariablesAre()
        {
            Console.WriteLine("The string, int are: {0}, {1}", myExtraString,mySpecialInt);
        }
        public override void printSpecialInt()
         {
             Console.WriteLine("at Leafail printSpecialInt");
         }
    }
    
    
    }
    

    【讨论】:

    • 以上是源代码,输出如预期:列表位于: //This Generic List 可能很麻烦,但执行得很好,接受基类和派生类都可以,没有问题。谢谢大家的回答。
    猜你喜欢
    • 2012-09-08
    • 2014-03-22
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2011-02-10
    相关资源
    最近更新 更多