3

過去数日間、私を悩ませてきた C# の問題があります。私がやっていることの抽象的な説明に基づいて説明しようと思います。簡単にフォローできることを願っています。;)

インターフェースがあるとしましょう

interface iFoo {
   void a();
}

さらに、たとえば、このインターフェイスとその中にあるメソッドを実装する 2 つのクラスがあります。

class bar1 : iFoo
{
   public void a() { Console.WriteLine("bar1"); }
   public void anotherMethodBar1() { Console.Write("I love "); }
}

class bar2 : iFoo
{
   public void a() { Console.WriteLine("bar2"); }
   public void anotherMethodBar2() { Console.Write("beer"); }
}

各クラスは、anotherMethodBar1() および anotherMethodBar2() という追加の固有メソッドも提供します。main() で、次のようなインターフェイスを実装するオブジェクトを含むリストを作成します。

namespace ExampleFooBar
{
    class Program
    {
        static void Main(string[] args)
        {
            List<iFoo> fooBarObjects = new List<iFoo>();
            fooBarObjects.Add(new bar1());
            fooBarObjects.Add(new bar2());

            for(int i = 0; i < fooBarObjects.Count; i++)
            {
                if(fooBarObjects[i].GetType() == typeof(bar1))
                {
                    //Cast element to bar1 and use anotherMethodBar1()
                }
                if(fooBarObjects[i].GetType() == typeof(bar2))
                {
                    //Cast element to bar2 and use anotherMethodBar2()
                }
            }
        }
    }
}

ご覧のとおり、各オブジェクト独自の (インターフェイスに含まれていない) メソッドを呼び出したいと思います (インターフェイスの一部ではない anotherMethodBar1() または anotherMethodBar2() を持つクラスに基づいて)。問題は - どうすればいいですか?私は C# が初めてで、これまでの私の経験はキャストとはほとんど関係がありませんでしたが、今はそれが必要です。これはキャストを使用して行われますか、それとも別の方法がありますか? 単純にメソッドを呼び出すことはできません

if(fooBarObjects[i].GetType() == typeof(bar1))
{
    fooBarObjects[i].anotherMethodBar1();
}

C# は下にある正確な型を理解していないため、このオブジェクトで使用できるメソッド/関数は、標準の 1 回と a() メソッドだけです。

  • ()
  • 等しい()
  • GetType()
  • GetHashCode()
  • ToString()

私は実際に解決策を見つけようとしましたが、これまでのところ、オブジェクトのリストからインターフェイスのリストへの変換という逆の質問しか聞かれませんでした。

どうもありがとうございました。よろしくお願いします!

4

4 に答える 4

8
        for(int i = 0; i < fooBarObjects.Count; i++)
        {
            if(fooBarObjects[i] is bar1)
            {
                ((bar1)fooBarObjects[i]).anotherMethodBar1();
            }
            else if (fooBarObjects[i] is bar2)
            {
                ((bar2)fooBarObjects[i]).anotherMethodBar2();
            }
        }

キーは、オブジェクトが型(または から派生した任意の型)isであるかどうかをチェックするキーワードと、オブジェクトを指定した型にキャストする構文です。bar1bar1(type)object

別のオプションは、キャストを実行し、キャストが実行できない場合にas戻るキーワードを使用することです。null

        for(int i = 0; i < fooBarObjects.Count; i++)
        {
            var b1 = fooBarObjects[i] as bar1;
            if  (b1 != null)
            {
                b1.anotherMethodBar1();
            }
            else
            {
                var b2 = fooBarObjects[i] as bar2;
                if (b2 != null)
                {
                    b2.anotherMethodBar2();
                }
            }
        }

2 番目のオプションは、最初のオプションよりも推奨されると見なされます。これは、ランタイムが 2 回 ( and )asではなく、1 回 (キーワードで) 型チェックを実行するだけで済むためです。is()

于 2013-06-12T11:00:11.793 に答える
1

as演算子を使用して、型に try-cast することができます。

for (int i = 0; i < fooBarObjects.Count; i++)
{
    var bar1 = fooBarObjects[i] as Bar1;
    if (bar1 != null)
        bar1.anotherMethodBar1();
    else {
        var bar2 = fooBarObjects[i] as Bar2;
        if (bar2 != null)
            bar2.anotherMethodBar2();
    }
}

これは、最も読みやすく、エラーが発生しにくいキャスト方法です。

于 2013-06-12T11:05:04.967 に答える
-1

キャストするだけです:)

(fooBarObjects[i] as bar1).anotherMethodBar1();

あなたが持っていたものを選ぶ

for(int i = 0; i < fooBarObjects.Count; i++)
{
   if(fooBarObjects[i].GetType() == typeof(bar1))
      (fooBarObjects[i] as bar1).anotherMethodBar1();
}
于 2013-06-12T11:17:10.647 に答える