2013-10-30 19 views
7

私は現在、コンパイルエラーが発生しています。私たちの会社の誰も助けてくれる人はいません。私は悲しいことにSOやGoogleの正しい検索パターンを見つけることができません。Delphi - ジェネリックでの継承インターフェイス

コードとして、私は2つのインタフェースを継承し、2つのクラスを継承しています。

program Project22; 

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

「TKeyObjectStorage」のコンパイルエラーがある: 次のコードは、エラーを再現し

[DCC Error] Project22.dpr(11): E2514 Type parameter 'T' must support interface 'IStorageObject'

私は、コンパイラが認識されていないこと、だと思う何そのクラスのTKeyObjectStorageのパラメータT '正しく。 希望のタイプ 'IKe​​yStorageObject'に親タイプIStorageObjectがあるので、正しいはずです。

なぜこれが機能しないのですか?私は間違って何をしていますか?これはDelphiでは不可能ですか?

+0

を!!:

documentationはこのことを念頭にあなたをカバーしていますか?そのコンマをセミコロンに置き換えましたか?あなたが投稿したコードはまだエラーを表示するのに十分ではありません。私が提案したものを行い、**完全なプログラム**を投稿してください。私は私の答えでどのようにあなたを示した。 –

+0

このDavidには申し訳ありませんが、私は行いましたが、 '、'はこのエラーを投げず、軽微な見落としに過ぎませんでした。もう一度お試しください。 – Hugie

+0

@Hugie、元の問題から逸脱して質問を変更しないでください。元々問題にあったエラーはすべて問題にとどまる必要があります。問題を示すために最小限のコードでコンソールアプリケーションを作成してください。ペースト**は**のコンソールアプリケーションの質問に。 – Johan

答えて

9

更新

元の質問は、私は(下記参照)を同定問題を抱えていました。しかし、私がそこに記述する修正はXE3以降では問題ありませんが、以下のプログラムはXE2でコンパイルされません。したがって、これはXE2ジェネリックコンパイラのバグであると結論づけます。

とにかく、ここでデルファイXE2の回避策です:

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>, IStorageObject> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IStorageObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

オリジナル答え

あなたは、コンパイラのエラーを示した完全なプログラムを提供した場合、それはもっと良かったはず。そのエラーを表示するには、オブジェクトをインスタンス化する必要があります。

しかし、私はあなたの問題を再現したと思います。

TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = ... 

TKeyTの両方に汎用的な制約が適用されます。だから私は、問題は、このコードがあることであると信じています。今、明らかにあなただけので、あなたが書く必要があります制約がTに適用する:

TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = ... 

ここデルファイXE3の変化を、以下のコンパイルの短いプログラムです:

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

このカンマをセミコロンに変更することはかなりのニュアンスです。重要な句読点によるプログラミングは決して楽しいものではありません。つまり、仮パラメータリストのカンマとセミコロンの違いに精通しているので、同じ区別がここに描かれているのは驚くべきことではありません。あなただけの完全に質問を変更しました

Multiple Type Parameters

When you specify constraints, you separate multiple type parameters by semicolons, as you do with a parameter list declaration:

type 
    TFoo<T: ISerializable; V: IComparable> 

Like parameter declarations, multiple type parameters can be grouped together in a comma list to bind to the same constraints:

type 
    TFoo<S, U: ISerializable> ... 

In the example above, S and U are both bound to the ISerializable constraint.

+1

Thx David、私は完全なユニット(インスタンス化なし)に自分のコードを編集し、クリーンなプロジェクトでエラーを再現します。 はい、あなたは正しかった、私はマイナーな論理的ミスを持っていました - >;それは私が対処しているエラーではありませんでした。 Thxあなたの努力のために。 – Hugie

+0

更新プログラムによってエラーは発生しません。それを試してみてください。新しいプロジェクトから始め、そのプロジェクトを追加してコンパイルします。それはコンパイルされますね。私が答えて言ったように、オブジェクトをインスタンス化する必要があります。私はこれで少し迷っています。あなたは時間を無駄にしないようにSSCCEを作る方法を学ぶ必要があります。私は今、昼食に出ます。私は質問が私が帰ってくるまでに修正されることを願っています。 –

+1

'[DCC Error] Project22.dpr(11):E2514タイプパラメータ 'T'は、この行でインターフェイス 'IStorageObject'をサポートしている必要があります:' TKeyObjectStorage < TKey; T:IKeyStorageObject > = class(TObjectStorage ) ' – Johan

関連する問題