2013-10-11 2 views
3

그래서 프로그래밍에 익숙하지 않고 부모 클래스의 형식을 확인한 다음 동일한 블록을 실행하는 메서드를 작성할 수 있는지 알아보기 위해 노력하고 있습니다. 결과에 대한 코드의 기본적으로 나는 여러 다른 자식 클래스가있을 때 else if 문에서 long if를 피하는 방법이 있는지 확인하려고합니다.동적 캐스팅 여러 자식 클래스 중 하나의 부모 클래스

예컨대

if (shape.GetType() == typeof(Rectangle)) var someShape = (Rectangle)shape; 
else if (shape.GetType() == typeof(Circle)) var someShape = (Circle)shape; 
else if (shape.GetType() == typeof(Polygon)) var someShape = (Polygon)shape; 

method(someShape) 
{ 
    doStuff... 
} 

당신이 위와 같이 VAR를 선언 할 수 없습니다 것을 알고도 그냥 수행 할 수 있습니다 : 대신

public Class Shape 
public Class Circle : Shape 
public Class Rectangle : Shape 
public Class Polygon : Shape 
.... 

Shape shape; 

if(shape.GetType() == typeof(Rectangle)) 
{ 
    var asRectangle = (Rectangle)shape; 
    doSomething(); 
} 
else if (shape.GetType() == typeof(Circle)) 
{ 
    var asCircle = (Circle)shape; 
    doSameSomething(); 
} 
else if (shape.GetType() == typeof(Polygon)) 
{ 
    var asPoly = (Polygon)shape; 
    doSame(); 
} 

의 같은 것을 수행

var dd; 
if(something) var = whatever; 

을하지만 궁금하네요 어쨌든 if, else if, else if, else if 문을 쓸 필요없이 메소드를 재사용 할 수있을 때마다 나는 모양을 가지고 뭔가를 할 필요가있다.

+3

는'abstract' virtual''로 기본 클래스의 메서드를 선언 또는 당신은'무시로 파생 클래스에서 다시 선언 할 수있다

public abstract class Shape { public abstract void SayMyName(); } public class Circle : Shape { public override void SayMyName() { Console.WriteLine("I'm a circle!"); } } public class Rectangle : Shape { public override void SayMyName() { Console.WriteLine("I'm a rectangle!"); } } public class Polygon : Shape { public override void SayMyName() { Console.WriteLine("I'm a polygon!"); } } 

그럼 당신은 이런 식으로 소모 될 수 있습니다 '키워드.이렇게하면 객체를 'Shape'으로 취급하고 공통 함수를 호출 할 수 있지만 인스턴스가 실제로 어떤 클래스에 해당하는지에 따라 적절한 메소드를 호출하게합니다. –

답변

3

기본 클래스의 메서드를 virtual 또는 abstract으로 선언하고 override 키워드를 사용하여 파생 클래스에서 다시 선언 할 수 있습니다. 이를 통해 객체를 Shape으로 처리하고 공통 함수를 호출 할 수 있지만 인스턴스가 실제로 어떤 클래스인지에 따라 적절한 메소드를 호출하게 할 수 있습니다.

List<Shape> shapes = new List<Shape>(new Shape[] 
{ 
    new Circle(), 
    new Rectangle(), 
    new Polygon(), 
}); 

foreach (Shape s in shapes) 
    s.SayMyName(); 
0

일반적으로 메서드를 Shape 클래스로 옮기고 호출하면됩니다. 메서드가 virtual (또는 abstract)이면 파생 형식의 실제 버전이 호출됩니다. 사용자 지정에 필요한

이는 등, Polygon, Circle, 당신은 잠재적으로 Shape 내에서 기본 구현을 제공 할 수 있고, Rectangleoverride을.

자세한 내용은 Virtual Methods on MSDN을 참조하십시오.

+0

굉장한 감사합니다. 원래 Shape 클래스는 일부 추상 속성을 사용하여 가상으로 만들었지 만 같은 Point에 대한 8 개의 다른 참조와 같은 것으로 나타났습니다. Shape.A, Shape.PointofPoints [0], Circle.A, Circle.ListofPoints [0], shapeAsCircle.A 등 ... 그리고 나는 내가 사용했던 참조를 기억하려고 노력하면서 길을 잃고 있음을 깨달았습니다. 참조를 Shape 및 하위 클래스에서 볼 수 없게하여 참조를 줄입니다. –

+0

@karmadeeds 그건 종종 자신에게 맞서고 있습니다. 기본 클래스에서 공유되는 것을 갖는 것이 더 낫습니다. 따라서 * 속성 및 메서드 사용 *이 더 간단 해졌습니다. –

+0

감사합니다. 프로그래밍에 대한 사전 지식이없는 첫 번째 "hello word"응용 프로그램을 시작했고 직접 가르치려고했지만 필자가 원하는 코드를 작성하는 방법을 배우는 것이 작성 방법을 배우는 것보다 훨씬 쉽습니다. 코드를 가장 효과적으로 그래서 나는이 같은 팁을 정말 고맙게 생각합니다. –

0

구현 프로그램이 아니라 인터페이스에 대한 프로그램입니다.

즉, 특정 클래스 자체 대신에 Shape 기본 클래스/인터페이스에 대해 작업을 수행하도록 코드를 작성해야합니다. 즉, 기본적으로 캐스팅하지 말고 필요에 따라 캐스팅해야합니다. 당신과 같이, 인터페이스로 Shape를 구현한다면 :

abstract class Shape { 
    public abstract Method() { ...} 
} 

는 그냥 shape.Method()를 호출하고 모든 파생 클래스에 대한 작동, 모든 캐스팅 할 필요가 없습니다.

또한이 작업을 수행하는 것이 더 쉽다 :

if (shape is Polygon) 

shape.GetType()를 호출보다.

+0

클래스도 추상 클래스 여야합니다. 그렇지 않으면 컴파일되지 않습니다. –

+0

감사합니다. 나는 코드를 작성하는 법을 스스로 가르치려고 노력하고 있으며, 배우는 것이 어렵다는 것을 이해하고 있습니다. 이 시점에서 내 코드가 작동한다는 것은 행복하지만, 어쨌든 내 아이디어를 얻기 위해 코드를 작성하는 법을 배워야합니다. –

관련 문제