.net C++;概括代表
我有一个类似的情况:.net C++;概括代表,.net,callback,delegates,c++-cli,.net,Callback,Delegates,C++ Cli,我有一个类似的情况: ref class Manager { delegate void answer1(String^ Message, int Avalue); delegate void answer2(Object^ Obj, double Something); answer1 ^ Callbackfor1; answer2 ^ Callbackfor2; void RegisterCallback1(answer1 ^ Address);
ref class Manager
{
delegate void answer1(String^ Message, int Avalue);
delegate void answer2(Object^ Obj, double Something);
answer1 ^ Callbackfor1;
answer2 ^ Callbackfor2;
void RegisterCallback1(answer1 ^ Address);
void RegisterCallback2(answer2 ^ Address);
}
我如何才能在更好的解决方案中实现这一点?每次我都必须为每次回调创建一个委托、一个指针和一个过程。有更好的概括方法吗?我认为每次都应该重新创建委托,但我希望避免重新创建过程和指针。首先,如果您公开
Callbackfor1
和Callbackfor2
(我假设您的类成员都是公共的)然后,您也不需要RegisterCallback1
和RegisterCallback2
:它们只是使调用方代码更加冗长的辅助方法:
manager->RegisterCallback1(YourMethod);
而不是:
manager->Callbackfor1 += YourMethod;
但是请注意,将代理公开后,您将完全公开它们,调用方可能会这样写:
manager->Answer1 = nullptr;
那么在我看来,您应该删除helper方法(保持字段公共)或保持helper方法(使字段私有)。还有另一种选择:事件。它们完全是委托,但不允许调用方设置它们(仅在调用列表中添加/删除函数):
请注意,使它们成为事件(或使它们保持私有)也会阻止调用方直接调用它们,您只能从您声明的类中引发事件。谁使用你的班级:
manager->Callback1 += YourMethod; // Add to invocation list
manager->Callback1 -= YourMethod; // Remove from invocation list
manager->Callback1 = nullptr; // Not allowed: it doesn't compile
manager->Callback1(L"some text", 0); // Not allowed: it doesn't compile
关于委托声明和签名:如果您的目标是新的.NET Framework版本,则可以使用Action
和Func
通用委托。像这样:
ref class Manager {
public:
event Action<String^, int>^ Callback1;
event Action<Object^, double>^ Callback2;
};
现在更改您的管理器
类:
ref class Manager {
public:
event EventHandler<Callback1EventArgs^>^ Callback1;
};
但方法签名不同:
void YourMethod(Object^ sender, Callback1EventArgs^ e) {
// In case you need it you have a reference to object
// that generated this "event".
Manager^ manager = safe_cast<Manager^>(sender);
// You find all your properties inside event arguments
Console::WriteLine(L"Message is {0} and value is {1}",
e->Message, e->Value);
}
将成为:
Callback1(this, gcnew Callback1EventArgs(L"Some message", 0));
这样更好吗?拥有一个类会让你的代码更加冗长,但是当参数改变时它会有很大的帮助:你只需要添加一个属性并重新编译(使用方法参数,你需要找到并更新每个方法寄存器作为
Callback1
的委托,并添加该参数,即使没有使用).您可以使用操作泛型类型来避免声明自己的委托类型。这是关于如何让它“更好”的问题,您确实需要创建委托对象并提供一个目标方法,这就是委托的工作方式。感谢您的回答,我正在寻找您的所有解决方案,这里有一个问题:事件操作^Callback1;该如何为其分配程序?这样做:委托void answer1(字符串^Message,int-Avalue);事件应答器1^Callbackfor1;我使用:经理cla;cla.Callbackfor1+=gcnew Manager::answer1(MyCall);如果您放弃回答1委托并使用标准的操作
则cla.Callbackfor1+=gcnew操作(…
,如果您保留answer1
委托,但将Callbackfor1
从delegate
更改为event
,那么就可以了。在我看来,您应该删除委托,移动到event
并将其与Callback1EventArgs
和EventHandle^
一起使用(最后一个示例)。
ref class Manager {
public:
event EventHandler<Callback1EventArgs^>^ Callback1;
};
manager->Callback1 += YourMethod;
void YourMethod(Object^ sender, Callback1EventArgs^ e) {
// In case you need it you have a reference to object
// that generated this "event".
Manager^ manager = safe_cast<Manager^>(sender);
// You find all your properties inside event arguments
Console::WriteLine(L"Message is {0} and value is {1}",
e->Message, e->Value);
}
answer1^ callbackfor1 = Callbackfor1;
if (callbackfor1 != nullptr)
callbackfor1(L"Some message", 0);
Callback1(this, gcnew Callback1EventArgs(L"Some message", 0));