假设我有一个类A
,它将被编译成dll
以便稍后使用。但是我后来知道,我不知道它的类型的类B
的一些方法必须在A
类中调用。唯一的线索是方法的名称。
让我们说这是班级A
:
public class A
{
A(Object instanceOfClassB)
{
//stuff...
}
public void SendProcessedString()
{
//some strings has been processd, I know that class B is going
//to have a public method like ReceiveData(string data){/*---*/}
instanceOfClassB.ReceiveData(data);
}
}
让我们说这是类B
,碰巧是WinForm:
public B : Form
{
public void ReceiveData(string data)
{
textBox.Append(data + Environment.NewLine);
}
}
这种方法是否可行/推荐?
答案 0 :(得分:5)
是的,可以使用dynamic
关键字(在C#4.0或更高版本中)。查看MSDN documentation了解详情。
然而,这会导致令人难以置信的松散编程,并且可能导致难以调试的运行时问题。你最好创建一个B类将实现的接口。
public class A
{
A(IDataReceiver instanceOfClassB)
{
//stuff...
}
public void SendProcessedString()
{
//some strings has been processd, I know that class B is going
//to have a public method like ReceiveData(string data){/*---*/}
instanceOfClassB.ReceiveData(data);
}
}
public B : Form, IDataReceiver
{
public void ReceiveData(string data)
{
textBox.Append(data + Environment.NewLine);
}
}
public interface IDataReceiver
{
void ReceiveData(string data);
}
答案 1 :(得分:2)
你应该使用界面。 B类必须实现“MyInterface”接口,“MyInterface”应该有预期A调用的方法。
public class A
{
A(MyInerface instanceOfClassB)
{
//stuff...
}
public void SendProcessedString()
{
//some strings has been processd, I know that class B is going
//to have a public method like ReceiveData(string data){/*---*/}
instanceOfClassB.ReceiveData(data);
}
}
如果无法在B类实现接口,则需要使用反射。请参阅此处(How to use reflection to call method by name),了解如何从Type调用方法(因此您必须在A的构造函数中传递类型。
答案 2 :(得分:2)
听起来你需要使用interface
。
可以找到关于interfaces
的一些信息here。
基本上您想要创建interface
并将其作为class A
的参数并在class B
中实施:
interface IDataReceiver
{
void ReceiveData(string data);
}
然后class B
decleration将如下所示:
public B : Form, IDataReceiver
和A类构造函数:
A(IDataReceiver dataReceiver)
{
//stuff...
}
答案 3 :(得分:2)
这里的另一个选择是使用事件。让你举起一个事件而不是调用回调。
原谅我的C#,我有点生疏
public class classA {
public event DataReceived(string data);
public void SendProcessedString() {
// you got var data from somewhere
DataReceived(data)
}
}
然后从您的classB订阅该事件
// classB setup code or initializer:
instanceA.DataReceived += dataReceivedHandler;
private void dataReceivedHandler(string data) {
// do something with the data.
}
答案 4 :(得分:1)
另一种方法是使用适当的回调 - 只有在保证单个订户的情况下。如果您需要多个订阅者,请使用活动。
public class classA {
public Action<string> DataReceivedCallback = null;
public void SendProcessedString() {
if (null != DataReceivedCallback) { DataReceivedCallback.Invoke(data); }
}
}
在classB
中的某个地方instanceA.DataReceivedCallback = new Action<string>(dataReceivedHandler);
private void dataReceivedHandler(string data) {
// do something with the data.
}