2

私はに拡張するクラスを持っていますControl:

public foo : Control 
{
  //.. 
}

そして、私はコントロールを取得します:

var baa = (((foo)((Control)Controls.Find(controlName, true).First()));
baa.etc = ..; 

しかし、私がするとき:

 ((PictureBox)((Control)controlImg)).MyExtensionMethod(..) 

例外が発生します:

タイプ 'System.Windows.Forms.PictureBox' のオブジェクトをタイプ 'ControlExtensions.foo' にキャストできません。

この例外を修正する方法を教えてください。

ありがとうございました。

4

2 に答える 2

4

これを修正する方法はありません。あなたのクラスfooは正しいです。エラーメッセージはそれをすべて説明しています。foo継承しませんPictureBoxfooがある種のピクチャ ボックスである場合は、 ではPictureBoxなくクラスを実装しControlます。

実際の例を挙げると:

interface IAnimal { }
class Dog : IAnimal { public static void Bark() { } }
class Cat : IAnimal { public static void Meow() { } }

の署名はas defined とCatは異なりますが、そうではありません。を定義しますが、定義しません。たとえば、コメント付きの次のコードは、これを理解するのに役立ちます。DogCatCat.Meow()DogDogDog.Bark()Cat

class Program
{
    static void Main(string[] args)
    {
        Dog myDog = new Dog(); // myDog contains definition for Bark
        IAnimal myPet = (IAnimal)myDog; // Cast not necessary.
                                        // myPet's signiature is of Dog, but typeof(myPet)
                                        //   is Animal as it was boxed (google for help on this)
        Cat myCat = (Cat)myPet // now try and imagine this in real life
                               // (turning a dog into a cat) [I don't even]
                               // It doesn't work because Cat doesn't
                               //   contain a definition for Bark()
        Cat myDimentedCat = (Cat)(IAnimal)myDog; // which is why this code fails.
    }
}


私が見せようとしているのは、次のものと同じですa square is a rectangle, but a rectangle isn't always a square:

interface IRectangle { }
interface ISquare : IRectangle { }
于 2012-06-06T04:03:00.977 に答える
0

コメントの Anthony と彼の回答の Cole の両方が、例外がどこから来たのかを示しました。それをどのように修正するかについては、あなたが意図していることを正確に理解しているかどうかはわかりませんが、呼び出そうとしているメソッドの名前を見て、foo が Control を「拡張」していると言っているので、 MyExtensionMethod を追加して、Windows フォーム コントロールの動作を拡張しようとしているように思えます。この場合、Control から派生した foo クラスを作成するのではなく、必要な拡張メソッドを含む静的クラスを作成する必要があります。つまり、コードは次のようになります。

public static class SomeControlExtensions
{
    public static int MyExtensionMethod(this Control aCtl)
    {
        // whatever you want
    }
} 

拡張メソッドには、メッセージの受信者を表す少なくとも 1 つの引数が常にあります。これは、引数の型の前にあるキーワード「this」によって識別されます。このようにして、これをコンパイルできます。

Control baa = (Control)Controls.Find(controlName, true).First();
baa.MyExtensionMethod();
于 2012-06-06T04:46:50.320 に答える