2012年9月1日土曜日

C++/CLIでIEnumerableを実装してみる。


サクッと実装する予定が"明示的なオーバーライド"ではまってしまったので、
残しておきます。


以下のように実装クラスを書いてコンパイル!
public ref class SampleList:public System::Collections::Generic::IEnumerable
{
public :
    virtual System::Collections::Generic::IEnumerator^ GetEnumerator() { return nullptr; }
    virtual System::Collections::IEnumerator^ System::Collections::IEnumerable::GetEnumerator() { return GetEnumerator(); }
};


すると。

エラー、エラー、エラー。。。。

error C3253: 'IEnumerable.GetEnumerator' : 明示的なオーバーライドでエラーが発生しました
error C2838: 'IEnumerable.GetEnumerator' : メンバ宣言内の限定名が間違っています。
error C3648: この明示的なオーバーライド構文には /clr:oldSyntax が必要です


明示的なオーバーライドは /clr オプションでは出来ないみたい。


調べるとMSDNさんにありました。
関数のオーバーライドを別の関数名にして実装が出来るとのこと。
http://msdn.microsoft.com/ja-jp/library/fw0bbh51(v=vs.80).aspx

これで書きなおしたのがこれ!
public ref class SampleList:public System::Collections::Generic::IEnumerable
{
public :
virtual System::Collections::Generic::IEnumerator^ GetEnumerator() { return gcnew Iterator(); }
virtual System::Collections::IEnumerator^ GetEnumeratorImpl() =System::Collections::IEnumerable::GetEnumerator { return GetEnumerator(); }
};


■参考サイト。
http://msdn.microsoft.com/en-us/library/fw0bbh51(v=vs.80).aspx


■おまけIEnumeratorの実装。
ref class Iterator : System::Collections::Generic::IEnumerator
{
    int i;
public:
Iterator()
{
i = -1;
}
virtual ~Iterator()
{
}


property virtual int Current
{
int get()
{
return i;
}
}
virtual System::Object^ CurrentImpl() = System::Collections::IEnumerator::Current::get
{
return Current;
}
virtual void Reset() = System::Collections::IEnumerator::Reset
{
throw gcnew NotImplementedException();
}


virtual bool MoveNext()
{
i++;
return i;
}


};



ラベル