C#委托教程工作

Der*_*rek 3 c# delegates

我之前没有使用过代表,我正试图按照我的书中的教程来解决这些问题.

到目前为止,我已经发现委托可以与类的方法一起使用,该类返回相同类型的对象,并且与调用委托的代理重载(如果我错了,请纠正我).

在我正在研究的教程中,以下代码被添加到Car Class:

public delegate void CarEngineHandler(string msgForCaller);

private CarEngineHandler listOfHandlers;

public void RegisterWithCarEngine(CarEngineHandler methodToCall)
{
   listOfHandlers = methodToCall;
}
Run Code Online (Sandbox Code Playgroud)

Main控制台应用程序中,调用以下代码:

static void Main(string[] args)
{
    Car c1 = new Car("Slugbug", 100, 10);

    c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));

    Console.WriteLine("**** Speeding Up ******");
    for (int i = 0; i < 6; i++)
        c1.Accelerate(20);
    Console.ReadLine();
}

public static void OnCarEngineEvent(string msg)
{
    Console.WriteLine("\n***** Message From Car Object *****");
    Console.WriteLine("=> {0}", msg);
    Console.WriteLine("*************************************\n");
}
Run Code Online (Sandbox Code Playgroud)

这是Accelerate方法:

public void Accelerate(int delta)
{
    if (carIsDead)
    {
        if (listOfHandlers != null)
            listOfHandlers("Sorry, this car is dead...");
    }
    else
    {
        CurrentSpeed += delta;

        if (10 == (MaxSpeed - CurrentSpeed) && listOfHandlers != null)
        {
            listOfHandlers("Careful buddy! Gunna Blow!");
        }
    }

    if (CurrentSpeed >= MaxSpeed)
        carIsDead = true;
    else
        Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
Run Code Online (Sandbox Code Playgroud)

我很困惑,究竟listofHandlers是怎么在这里工作的?我知道这不是任何代码的错,但我想更多地了解代表的实际工作方式?检查那listofHandlersnull让我失望......

Dan*_*ker 10

定义代表

在C#中,您可以创建指向方法的指针.这样的指针称为a Delegate.委托只是具有方法的普通对象.它只能指向具有匹配参数类型和匹配返回类型的方法.

delegate string MyHandler(int value1, string value2);
Run Code Online (Sandbox Code Playgroud)

定义一个委托类型,该类型可以指向具有(int,string)作为参数类型并返回a的方法string.

您可以在字段中存储这样的委托(指向方法的指针).

MyHandler myhandler;
Run Code Online (Sandbox Code Playgroud)

这个委托只是一个对象,所以它可以像任何对象一样null.

创建一个新的委托

给定一种方法:

string X(int v1, string v2) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

您可以创建指向该方法的新委托:

myHandler = new MyHandler(X);
Run Code Online (Sandbox Code Playgroud)

或者,由于语法糖,您可以使用这种更短的语法:

myHandler = X;
Run Code Online (Sandbox Code Playgroud)

调用委托

在以后的任何时候,您都可以调用委托指向的方法.

int i = 10;
string s = String.Empty;
string result = myHandler.Invoke(i, s);
Run Code Online (Sandbox Code Playgroud)

或者,再次感谢句法糖:

int i = 10;
string s = String.Empty;
string result = myHandler(i, s);
Run Code Online (Sandbox Code Playgroud)

当然myHandler可以null,所以你需要先检查一下,否则你会得到一个NullReferenceException.毕竟,你无法调用实例方法null.

myHandler = null;
myHandler.Invoke(10, "");
Run Code Online (Sandbox Code Playgroud)

所以,他们检查:

string result;
if (myHandler != null)
    result = myHandler(i, s);
Run Code Online (Sandbox Code Playgroud)

或几乎等同,在C#6:(请注意,resultnullmyHandlernull.)

string result = myHandler?.Invoke(i, s);
Run Code Online (Sandbox Code Playgroud)

为什么代表?

如果要使用相同的代码调用不同的方法,则可以传递一个委托,该委托指向要在对象中作为参数或字段调用的方法.这就是.NET中实现事件的方式,以及LINQ的工作原理.

  • 我非常感谢您的解释,这正是我所寻找的,这就是像我这样的人可以学习 .Net 开发的方式 (2认同)