Delegate to an instance method cannot have null 'this'

Jim*_*ell 10 c# delegates

I am developing a C# .NET 2.0 application wherein at run-time one of two DLLs are loaded depending on the environment. Both DLLs contain the same functions, but they are not linked to the same address-offset. My question is regarding the function delegates in my application code.

public class MyClass
{
    public delegate int MyFunctionDelegate(int _some, string _args);

    public MyFunctionDelegate MyFuncToCallFrmApp;

    public MyClass() : base()
    {
        this.MyFuncToCallFrmApp = new MyFunctionDelegate(this.MyFuncToCallFrmApp); // <-- Exception thrown here.
    }

    public SomeFunction()
    {
        MyFuncToCallFrmApp(int _someOther, string _argsLocal);
    }
}
Run Code Online (Sandbox Code Playgroud)

When my code executes I get an ArgumentException of "Delegate to an instance method cannot have null 'this'." What am I doing wrong?

Jef*_*nal 11

您需要将一个有效的函数(由动态加载的dll中的某个类托管)分配给您的委托变量.如果函数是具有相同名称的类的静态方法,则这很简单:

public MyClass() {
    this.MyFuncToCallFrmApp = ExternalClass.Function;
}
Run Code Online (Sandbox Code Playgroud)

如果函数是具有相同名称的类的实例方法,只需创建一个实例并执行相同的操作(还要注意,只要委托在范围内,它将阻止ExternalClass实例被垃圾收集 - 您可能希望将实例存储为成员变量以使其更清晰):

public MyClass() {
    this.MyFuncToCallFrmApp = new ExternalClass().Function;
}
Run Code Online (Sandbox Code Playgroud)

如果动态加载的类具有不同的名称,则需要确定要调用哪一个 - 在此示例中,我使用布尔成员变量来决定是否使用默认程序集的类:

public MyClass() {
    if (this.defaultAssembly) {
        this.MyFuncToCallFrmApp = ExternalClass1.Function;
    } else {
        this.MyFuncToCallFrmApp = ExternalClass2.Function;
    }
}
Run Code Online (Sandbox Code Playgroud)


Kir*_*oll 10

在你的行:

this.MyFuncToCallFrmApp = new MyFunctionDelegate(this.MyFuncToCallFrmApp); 
Run Code Online (Sandbox Code Playgroud)

您在分配之前使用"this.MyFuncToCallFrmApp",这意味着它在分配期间为空.让代表指向自己毫无意义.那是你想要做的吗?


Jus*_*ner 5

您尝试使用类中已有的未初始化的委托实例创建委托的新实例...这是没有意义的。

您需要使用类中具有匹配参数列表作为委托的方法来初始化委托,或者不初始化委托并允许类的使用者使用其代码中的匹配方法来初始化委托(这就是代表通常用于):

public class MyClass
{
    public delegate int MyFunctionDelegate(int some, string args);
    public MyFunctionDelegate MyFuncToCallFrmApp;

    public MyClass() : base() { }
    public SomeFunction()
    {
        if(MyFuncToCallFrmApp != null)
            MyFuncToCallFrmApp(_someOther, _argsLocal);
    }
}

public class Consumer
{
    MyClass instance = new MyClass();

    public Consumer()
    {
        instance.MyFuncToCallFrmApp = new MyFunctionDelegate(MyFunc);
    }

    public void MyFunc(int some, string args)
    {
        // Do Something
    }
}
Run Code Online (Sandbox Code Playgroud)