8

コンテキスト: .NET 4.0、C#

私は一連のインターフェースと、それらを実装して何らかのサービスを提供する一連のクラスを作成しています。クライアントは具体的なクラスを使用しますが、インターフェイスをパラメーターの型として使用して宣言されたメソッドを呼び出します。

簡単な例は次のとおりです。

namespace TestGenerics
{
    // Interface, of fields
    interface IField
    {
    }

    // Interface: Forms (contains fields)
    interface IForm<T> where T : IField
    {

    }

    // CONCRETE CLASES
    class Field : IField
    {   
    }

    class Form <T> : IForm<T> where T : IField
    {
    }

    // TEST PROGRAM
    class Program
    {
        // THIS IS THE SIGNATURE OF THE METHOD I WANT TO CALL
        // parameters are causing the error.
        public static void TestMethod(IForm<IField> form)
        {
            int i = 1;
            i = i * 5;
        }

        static void Main(string[] args)
        {
            Form<Field> b = new Form<Field>();
            Program.TestMethod(b);
        }
    }
}

コードは理にかなっていますが、コンパイラ エラーが発生します。

引数 1: ' TestGenerics.Form<TestGenerics.Field>'から ' TestGenerics.IForm<TestGenerics.IField>'に変換できません

インターネットで多くのページを読みましたが、問題を解決するものはありませんでした。

私が構築しようとしているもののアーキテクチャをそれほど変更しないソリューションはありますか:

編集:インターフェイスを実装する具体的なクラスから独立するようにインターフェイスを設計しました。具体的なクラスは dll からロードできますが、ほとんどのアプリケーションはインターフェイスで動作します。場合によっては、具体的なクラスを使用する必要があります。特に、シリアル化する必要があるクラスを使用する場合です。

前もって感謝します。

アレハンドロ

4

3 に答える 3

7

他の人がエラー メッセージの背後にある理由を指摘していますが、サンプル コードの設計を少し調べてみましょう。おそらく、何も必要ないジェネリックを使用しています。

IField インターフェイスで宣言されたメソッドを使用していると既に述べたので、IForm クラスをジェネリックにする必要はないかもしれません。ジェネリック引数 'T' の代わりに IField への参照を格納するだけです (これは既に保証されています)。とにかく IField であること)。

たとえば、次を使用します。

public interface IForm
{
    IEnumerable<IField> Fields { get; set; }
}

それ以外の

public interface IForm<T> where T : IField
{
    IEnumerable<T> Fields { get; set; }
}
于 2013-07-30T16:20:25.917 に答える