2013-05-14 2 views
6

I가 다음 코드Delphi 인터페이스 일반 함수 - 해결 방법이 있습니까?

IProxy<T> = interface 
    ['{1E3A98C5-78BA-4D65-A4BA-B6992B8B4783}'] 
    function Setup : ISetup<T>; 
    function Proxy : T; 
    function CastAs<I : IInterface> : IInterface; 
end; 

컴파일 할 때 수신 된 컴파일러 오류를 해결하는 방법이 있나요?

"[DCC 오류] Delphi.Mocks.pas (123) : E2535 인터페이스 방법은 매개 변수화 방법이 안된다"나는이 인터페이스를 건네 줄 수가 있고 그것을 버리 수 있도록하고 싶습니다 기본적으로

을, 에 캐스트 할 유형을 전달하고 해당 유형을 리턴합니다. 클래스를 사용하여이 작업을 수행 할 수 있지만 인터페이스 주위를 돌아 다니는 것이 더 좋습니다.

추가 정보 :

내가

TInterfaceProxy<T> = class(TBaseProxy<T>) 
private type 
    TProxyVirtualInterface = class(TVirtualInterface) 
    private 
    FProxy : TInterfaceProxy<T>; 
    protected 
    public 
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; override; stdcall; 
    constructor Create(AProxy : TInterfaceProxy<T>; AInterface: Pointer; InvokeEvent: TVirtualInterfaceInvokeEvent); 
    end; 
private 
    FVirtualInterfaces : TDictionary<TGUID, TProxyVirtualInterface>; 
protected 
    function InternalQueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall; 
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; override; 
    function Proxy : T;override; 
    function CastAs<I: IInterface> : I; 
public 
    constructor Create;override; 
    destructor Destroy;override; 
end; 

CastAs 잘 여기에 새로 요청 캐스트가 새로운 가상 인터페이스를 생성 할 수 있습니다로 작동 다음 클래스를 말한다. 이제이 클래스를 벌금 주위로 전달하고 싶습니다. 그러나 인터페이스 (예 : TInterfaceProxy<T> = class(TBaseProxy<T>, IProxy<T>))가 필요한 경우이를 이해할 수 없습니다. 그것에 동의하지 말고 이해하십시오.

따라서 CastA 함수를 호출하고 유형 (모든 인터페이스 유형)을 전달하고 가상 인터페이스를 생성 할 수 있도록이 제한 사항을 해결하려면 어떻게해야합니까?

답변

12

인터페이스는 컴파일러에서 말한 것처럼 일반적인 매개 변수화 된 메서드를 지원하지 않습니다.

근본적인 제한 사항이므로 해결 방법이 없습니다. 클래스의 매개 변수화 된 메서드는 클래스에 인스턴스화 당 하나의 메서드를 추가하여 구현됩니다. 그것들은 구체적이기 때문에 클래스에서 작동하지만, 인터페이스에서는 실행 가능하지 않습니다. 왜냐하면 인터페이스는 함수 테이블이며 그 테이블의 크기는 코드의 다른 곳에서 어떤 일반적인 메소드 인스턴스화가 발생하는지에 따라 달라질 수 없기 때문입니다. 비슷한 이유로 일반 메소드는 가상 또는 동적 일 수 없습니다.

귀하의 질문에있는 코드도 약간 잘못 이해하고 있습니다.당신이 쓴 :

function CastAs<I : IInterface> : IInterface; 

하지만 난 당신이 의미 확신 : 어떤 경우에

function CastAs<I : IInterface> : I; 

, 그것은 불가능합니다. 하나의 옵션은 대신 클래스를 사용하는 것입니다. 저는 이것이 구속력이라는 것에 동의합니다.

function CastAs(const IID: TGUID): IInterface; 

하지만 당신은 다음과 같이 호출해야 할 것 :

당신이 인터페이스를하고 싶은 경우에, 당신이 할 수있는 최선입니다

MyIntf := ProxyIntf.CastAs(IMyIntf) as IMyIntf; 

파울 다소 느끼는 .

독을 선택하십시오!

+0

감사합니다. 나는 TGUID가 지나가고 가서 그걸로 살아야한다고 믿습니다. 또한 클래스를 외부에 노출 시키지만 인터페이스 "function CastAs (const IID : TGUID) : IInterface;"를 유지하십시오. 내부의. "프로그램을 당신의 언어로, 그렇지 않으면" "http://programmers.stackexchange.com/questions/2777/what-are-the-key-points-of-code-complete – Jason

+0

" function CastAs : 나는 코드를 복사하는 실수를 저지른다. – Jason

5

오류 메시지에서 알 수 있듯이 인터페이스의 메서드에는 Generic 매개 변수를 사용할 수 없습니다. 컴파일러는 단순히 지원하지 않으며,이 같은 설명되어 인터페이스

http://docwiki.embarcadero.com/RADStudio/XE4/en/Overview_of_Generics

변수화 방법

매개 변수화 방법 (입력 변수로 선언 된 메소드)에서 선언 될 수 없다 인터페이스.

즉, 인터페이스 유형으로 선언되었으므로 CastAs 메서드는 유효하지 않습니다. 반면에, 당신은 처음에는 그런 방법을 필요로하지 않습니다. 인터페이스를 다른 인터페이스로 캐스팅하는 대신 SysUtils.Supports()을 사용할 수 있습니다.

+0

직접 이해하지 말고 이해하십시오. 컴파일러에서 무엇을 말하는지, 왜 델파이에서 문제인지를 이해하십시오. 디자인에 동의하지 않고, 델파이의 한계를 극복하기 위해 왜 디자인을해야하는지 찾아야합니다. 현재 개체를 전달하는 것이 슬프게도 유일한 방법이라고 생각합니다. 의견에 감사드립니다. – Jason

관련 문제