2011-11-08 2 views
3

인터페이스에서 선언 된 개체 메서드 외에 추가 개체 메서드를 사용할 수 있도록 C#에서 개체를 캐스팅하는 데 약간의 문제가 있습니다. 다음은 내가 말하는 것에 대한 간단한 예입니다.모든 개체 기능을 사용할 수 있도록 인터페이스로 C#으로 캐스팅

public interface IShape 
{ 
    void Print(); 
} 

public class Square : IShape 
{ 
    #region IShape Members 

    public void Print() 
    { 
     HttpContext.Current.Response.Write("Square Print Called"); 
    } 

    #endregion 

    public void PrintMore() 
    { 
     HttpContext.Current.Response.Write("Square Print More Called"); 
    }   
} 

왜이 코드를 호출 할 때 PrintMore()에 액세스 할 수 없습니까?

IShape s = (Square)shape; 
s.PrintMore() // This is not available. only Print() is. 

도움이 될만한 설명이 있습니까? 이 코드 s

+1

개체가 "정사각형"이 아니며 "정사각형"이 아니기 때문에. 던지기 "문제점"이다. 그것은 완전히 정상적입니다 :) – ykatchou

+0

귀하의 끝 영역이 잘못된 위치에 있습니다. 그것은 다소 혼란 스럽습니다. – CodesInChaos

+0

@CodeInChaos : 나는 그렇게 생각하지 않습니다. 인터페이스에는 단 하나의 메소드가 있으며 그 메소드는 region 내부에 있습니다. 비 인터페이스 방법이 그것의 외부에 있습니다 ... – Chris

답변

5

귀하의 s 변수는 유형 IShape의 아직도있다. 컴파일러가 관심을 가질 때까지 유형을 변경하지 않을 때 캐스트를 사용했기 때문에 발생합니다. 당신은해야 할 것 : shape 정말 가 (계속 사용자 정의 변환이없는 가정)Square 경우

물론
Square s = (Square) shape; 
s.PrintMore(); 

, 이것은에만 작동합니다.

이 경로를 사용하기 전에 신중하게 생각해 보라고 조언합니다. 일반적으로이 같은 캐스트는 다소 추상적 인 개념을 깨고 있음을 나타냅니다. 을 IShape으로 알면 이어야합니다 (보통은 IShape의 구성원 만 필요). 그런 경우가 아니라면, 당신은 할 수 있습니다

  • 가 대신 IShape
  • 캐스트의 Square를 허용하도록 코드를 변경
  • IShape 더 강력한 (을주고 더 많은 회원을) 확인 절대적으로 필요한 경우
+0

디자인 고려 사항에 우수 점 ... –

+0

점을 주셔서 감사합니다. 나는 정확한 접근법과 그것의 추론을 완전히 이해한다는 점에 착수하려고 시도하고있다. 때때로 해결책은 훌륭하지만, 왜 당신이 이해하지 못한다면 도움이되지 않습니다. – Dietpixel

2
IShape s = (Square)shape; 
s.PrintMore(); 

여전히 IShape 아닌 Square입니다. 변수는 선언에서 정의한 유형을 유지하려고 시도하는 모든 것을 유지합니다.

코드가 있어야합니다하려면 :

Square s = (Square)shape; 
s.PrintMore(); 
+0

이것은 실제로 그의 질문에 대답하지 않습니다 - 왜? –

+0

@ JoeEtherton : 몇 가지 설명을 추가했습니다. – Matthieu

3

를 줄 당신은 IShape에 IShape 그래서 단지 방법을 사용할 수 있습니다이야 컴파일러를 말하고있다 IShape s = (Square)shape;.

당신이 만약 사용자 :

Square s = (Square)shape; 
s.PrintMore() 

는 그런 다음 당신이 원하는 일을해야한다.

여기서 중요한 점은 변수를 선언 할 때 컴파일러에게 무엇이 무엇인지 알려주고 어떤 객체를 넣었는지 문제가되지 않는다는 것입니다.

4

문제는 당신이 IShape 참조 오프 액세스 PrintMore()하려고하는 것입니다, IShape 참조는 그들 만이 선언 Print() 방법을 참조하십시오.

따라서 (Square) shape의 캐스트는 즉시 IShape 참조에 저장되므로 아무 작업도 수행하지 않습니다. 당신이 중 하나를 주조하여 SquareSquare 참조에 저장 될 기준 자체가 필요하거나 호출하기 전에 캐스트 : 당신이 만약 확실하지 않은 경우

Square s = (Square) shape; 
s.PrintMore(); 

또는

IShape s = shape; 
((Square)s).PrintMore(); 

또는,

Square s = shape as Square; 

// will cast if it is a Square, otherwise, returns null 
// this doesn't work for value types (int, struct, etc) 
if (s != null) 
{ 
    s.PrintMore(); 
} 
+0

의견 주셔서 감사합니다. – Dietpixel

1

당신이에 액세스 할 수없는 이유 : 그것은 Square 여부, as 캐스트를 사용입니다210 메서드는 타입 캐스트 된 모양을 IShape으로 정의 된 변수로 다시 할당하기 때문입니다. 그것이 좋은 모습을 복용 가치가있을 수도 있지만

((Square) shape).PrintMore(); 

:

Square s = (Square)shape; 
s.PrintMore(); 

또는 대안 : 당신은 예를 들어 유형 Square의 변수에 저장하는 데 필요한 Square 클래스에 메소드를 사용할 수 있도록 코드에서 이러한 타입 캐스트는 일반적으로 이상적이지 않은 좋은 경고 신호입니다.아마도 IShape에는 PrintMore 방법이 있어야하며, 현재로서는 Square 개의 개체 만 수락해야합니다. 적어도이 유형 캐스트를 수행하기 전에 shape이 실제로 Square 유형인지 확인하는 것이 좋습니다. 예를 들어

:

Square s = shape as Square; 

if (s != null) 
    s.PrintMore(); 
1

시도 할 때 s.PrintMore() "s"는 유형이 IShape이므로 인터페이스 함수에 대해서만 알고 있습니다. 당신은 인터페이스에 정의 된 함수 만 노출 개체에 대한 래퍼 같은 인터페이스의

Square s = (Square)shape; 
s.PrintMore(); 

또는

((Square)shape).PrintMore(); // assuming you're positive its a Square type 

생각해처럼 뭔가를해야 할 것입니다. 그들은 여전히 ​​거기에있어, 당신은 단지 적절한 개체에 캐스트하지 않고 액세스 할 수 없습니다.

관련 문제