2012-07-26 4 views
1

파생 클래스와 기본 클래스를 기본 클래스 유형 인 C#의 일반 목록에 혼합 할 수 있습니까? 나는 왜 안 보이지 않는가? 그리고 이것에 대한 명확한 답을 얻지 못한다 ... 그러나 기본 클래스 유형의 일반 목록으로 오늘 놀아 보면 클래스에 파생 된 클래스가 있는데 아무 것도 보지 못했다. 문제. 그러나 파생 된/기본 클래스에 항상 내재 된 일반적인 upcast/downcast 제한을 제외하고 잠재적 인 문제가있을 수 있는지 궁금합니다. 내가 묻는 이유 : C#의 일반적인 목록이 C++에서 ArrayList라고 불리는 것과 똑같이 작동하는지, 즉이 '유형'을 혼합하기 위해 컴파일하는 동안 불만을 제기하는지 여부는 알지 못합니다 (기본 대 파생 된 클래스). 오늘 불만없이 수많은 예제를 실행했지만 문제가 발생할 가능성이 있는지 확인하려고합니다.파생 클래스와 기본 클래스를 기본 클래스 유형 인 C#의 일반 목록에 혼합 할 수 있습니까?

+0

음, 어떻게 파생 클래스에 추가 된 항목이 있습니까, 아니면 다른 이름을 가진 기본 클래스입니까? 당신의 모범을 보여줄 수 있습니까? – V4Vendetta

+0

자바와 C++과 비교하여 C#의 제네릭 클래스를 더 잘 이해하기 위해이 [SO 질문]을 볼 수 있습니다 (http://stackoverflow.com/questions/31693/what-are-the-differences-between-generics-in -c-sharp-and-java-and-templates-i). – Rafal

답변

1

C# 클래스 유형은 참조 유형입니다. C++ 클래스 유형은 .NET 환경에서 값 유형이라고합니다. 적절한 비교는 파생 클래스에 대한 포인터를 아무 문제없이 저장할 수있는 기본 클래스 포인터의 C++ 목록입니다.

그래, 괜찮아.

0
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"); 
    } 
} 


} 
+0

위의 코드는 소스 코드이며 예상대로 출력됩니다 : //이 일반 목록은 문제가 될 수 있지만 잘 실행 되었기 때문에 기본 클래스와 파생 클래스를 모두 수용해도 괜찮습니다. 모두에게 감사드립니다. – PaulDecember

관련 문제