2016-04-30 6 views
-1

私はclassTwoを数えることに目を向けようとしてきましたが、私が見ているリソースのほとんどがそれらのコードのこのセクションを持っているので、私はかなり理解していません...Invalid Casting Exceptionエラーを受け取らずに、このサブクラスをどのように列挙しますか?

public IEnumerator GetEnumerator() { 
    return (IEnumerator)this; 
} 

しかし、返信行にエラーが表示されています。ここに私のコードの残りの部分があります...

class classOne { 
    public float x; 
    public float y; 
    public float Z; 

    public classOne() { 
     x = 0; 
     y = 0; 
     z = 0; 
    } 

    public classOne(float X, float Y, float Z) { 
     x = X; 
     y = Y; 
     z = Z; 
    } 
} 
class classTwo { 
    public classOne a; 
    public classOne b; 
    public classOne c; 


    public classTwo() { 
     a = new classOne(); 
     b = new classOne(); 
     c = new classOne(); 
    } 

    public IEnumerator GetEnumerator() { 
     return (IEnumerator)this; 
     //Error: InvalidCastException: Cannot cast from source type to destination type. 
    } 
} 

答えて

1

this sample codeを見てください。

まず、

return (IEnumerator)this; 

classTwoはそうあなたがIEnumeratorとしてそれをキャストすることはできませんIEnumeratorを実装していません。

また、classTwoが列挙されることを意味する場合は、IEnumerableを実装する必要があります。 IEnumeratorを実装する別のクラスを定義し、次にGetEnumeratorはそのクラスのインスタンスを返します。

+0

IEnumeratorを実装する方法がわからないので、私が作成したクラスで動作します。私のクラスを 'foreach'で使えるようにするために、サンプルコードでリンクしたものをすべて新しいクラスにする必要がありますか? – Wafer

+0

実際にこのクラスをforeachループで使用する場合は、配列やコレクションを使用しないのはなぜですか? – yes

+0

実際には.NET 1.1以降はこれを実装していません。いったん汎用コレクションがあれば、私はそれを必要としませんでした。私はそれを実装する理由があると確信しています。私は1つに遭遇しなかったか、それを認識しなかった。 –

1

classTwoIEnumeratorではないため、エラーが発生しています。あなたはそれが(class classTwo : IEnumerator)であることを宣言してからIEnumeratorインタフェースのメソッドを実装(CurrentMoveNext()を、そしてReset())する必要があります。

class classTwo : IEnumerator { 

    public object Current {get;} 
    public bool MoveNext() { ... } 
    public void Reset() { ... } 

    ... 

    public IEnumerator GetEnumerator() 
    { 
     return this; 
    } 
} 

あなただけforeach声明でそれが使えるようにしたい場合は、私はそのはIEnumerableを/のIEnumeratorを実装する方法の質問に答えていない知っているが、すべてのフィールドがアーカンソー以来

public IEnumerator GetEnumerator() 
{ 
    yield return a; 
    yield return b; 
    yield return c; 
} 
0

yield文を使って、イテレータを書くことができますeを同じ型(classOne)にするには、ArrayまたはCollection(特定のList)を使用して、foreachループにプラグインできるように参照を「バンドル」することができます(コメントの1つから取ったもの) 。 classTwoは、少なくとも現在の形では、冗長になります。

usuage例

//if you know how many elements it will be, use an array 
ClassOne[] classOneArray = new ClassOne[3]; 
ClassOne[0] = new ClassOne(); //a 
ClassOne[1] = new ClassOne(); //b 
ClassOne[2] = new ClassOne(); //c 
foreach(ClassOne element in classOneArray) { 
    //do smthg 
} 

//if you dont know how many elements it will be, use a list 
List<ClassOne> classOneList = new List<ClassOne>(); 
classOneList.Add(new ClassOne()); //a 
classOneList.Add(new ClassOne()); //b 
classOneList.Add(new ClassOne()); //c 
foreach(ClassOne element in classOneList) { 
    //do smthg 
} 

List<T> System.Collections.Genericを使用する必要があります - また、あなたのデータがレイアウトさ必要があるかに応じて、使用可能な他のコレクションの全体の束があります。

インターフェイスを自分で実装し、他の2つの回答を参照する必要がある特定のユースケースがある場合は、その答えを無視してください。

+0

申し訳ありません使用したい実際のクラスはちょっと違うだけです。質問を簡単にするためにフィールドをたくさん削除しました。他の2つの答えは本当に私に十分な情報を与えていない、私は彼らが私のクラスで働くために与えてくれたものをどのように変更するか分からない。 – Wafer

関連する問題