ため込んでいたネタの1つ放出です。

C++/CLIにはUnbound delegateというものがあり、thisを第一引数に持ってきた形のデリゲートを認めています。 – 参考: Unbound Delegates – Visual C++ Language Reference (MSDN Library)。何が言いたいかというと、インスタンスメソッド,this, デリゲートへの束縛可能性 – NyaRuRuの日記、そのコード、C++/CLIでは、リフレクションを使わずとも書けます。

ところどころ適当に書き換えて、同じ出力となるコードになっていません。出力はよろしく察してください。

using System::String;
 
ref class Foo
{
public:
	property String^ Name;
	String^ GetStr(int)
	{
		if (this != nullptr)
			return String::Format("My name is {0}", this->Name);
		else
			return String::Format("this is null!");
	}
 
	virtual String^ ToString() override
	{
		return "I'm Foo";
	}
};
 
delegate String^ GetStrDelegate(Foo^, int);
 
int main()
{
	using namespace System;
 
	Foo^ foo = gcnew Foo;
	foo->Name = "tekitou";
 
	//Unboundなデリゲート
	GetStrDelegate^ f1 = gcnew GetStrDelegate(&Foo::GetStr);
 
	Console::WriteLine(f1(foo, 1));
	Console::WriteLine(f1(nullptr, 2));
 
	//比較用にリフレクション使った版
	Reflection::MethodInfo^ mi = Foo::typeid->GetMethod("GetStr");
	GetStrDelegate^ f2 = dynamic_cast<GetStrDelegate^>(
		Delegate::CreateDelegate(GetStrDelegate::typeid, mi));
 
	Console::WriteLine(f2(foo, 1));
	Console::WriteLine(f2(nullptr, 0));
 
	Console::WriteLine();
 
	//仮想メソッド編
	typedef Func<Object^, String^> FN;
 
	FN^ toString = gcnew FN(&Object::ToString);
	Console::WriteLine(toString(gcnew Object));
	Console::WriteLine(toString(gcnew Foo));
	return 0;
}

VC++ 2008 EEだとVC#と違い、自分でSystem.Core.dllを参照を設定しないといけません。LINQ(のクエリ構文)が使えない言語だからでしょう。

スポンサード リンク

この記事のカテゴリ

  • ⇒ UnboundなDelegate
  • ⇒ UnboundなDelegate