Can someone distill into proper English what a del

2019-01-11 07:08发布

Can someone please break down what a delegate is into a simple, short and terse explanation that encompasses both the purpose and general benefits? I've tried to wrap my head around this and it's just not sinking in.

标签: c# delegates
11条回答
Emotional °昔
2楼-- · 2019-01-11 07:29

It simply references a method. They come in great use with working with cross threading.

Here is an example right out of my code.

 //Start our advertisiment thread
    rotator = new Thread(initRotate);
    rotator.Priority = ThreadPriority.Lowest;
    rotator.Start();

    #region Ad Rotation
    private delegate void ad();
    private void initRotate()
    {
        ad ad = new ad(adHelper);
        while (true)
        {
            this.Invoke(ad);
            Thread.Sleep(30000);
        }

    }

    private void adHelper()
    {
        List<string> tmp = Lobby.AdRotator.RotateAd();
        picBanner.ImageLocation = @tmp[0].ToString();
        picBanner.Tag = tmp[1].ToString();            
    }
    #endregion

If you didnt use a delegate you wouldn't be able to crossthread and call the Lobby.AdRotator function.

查看更多
贪生不怕死
3楼-- · 2019-01-11 07:31

It's interesting that no-one has mentioned one of key benefits of delegation - it's preferable to sub-classing when you realise that inheritance is not a magic bullet and usually creates more problems than it solves. It is the basis of many design patterns, most notably the strategy pattern.

查看更多
何必那么认真
4楼-- · 2019-01-11 07:32

In the absolute most simplest terms I can come up with is this: A delegate will force the burdens of work into the hands of a class that pretty much knows what to do. Think of it as a kid that doesn't want to grow up to be like his big brother completely but still needs his guidance and orders. Instead of inheriting all the methods from his brother (ie subclassing), he just makes his brother do the work or The little brother does something that requires actions to be taken by the big brother. When you fall into the lines of Protocols, the big brother defines what is absolutely required, or he might give you flexibility to choose what you want to make him do in certain events (ie informal and formal protocols as outlined in Objective-C).

The absolute benefit of this concept is that you do not need to create a subclass. If you want something to fall in line, follow orders when an event happens, the delegate allows a developed class to hold it's hand and give orders if necessary.

查看更多
祖国的老花朵
5楼-- · 2019-01-11 07:33

I have a function:

public long GiveMeTwoTimesTwo()
{
    return 2 * 2;
}

This function sucks. What if I want 3 * 3?

public long GiveMeThreeTimesThree()
{
    return 3 * 3;
}

Too much typing. I'm lazy!

public long SquareOf(int n)
{
    return n * n;
}

My SquareOf function doesn't care what n is. It will operate properly for any n passed in. It doesn't know exactly what number n is, but it does know that n is an integer. You can't pass "Haha not an integer" into SquareOf.

Here's another function:

public void DoSomethingRad()
{
    int x = 4;
    long y = SquareOf(x);
    Console.WriteLine(y);
}

Contrary to its name, DoSomethingRad doesn't actually do anything rad. However, it does write the SquareOf(4) which is 16. Can we change it to be less boring?

public void DoSomethingRad(int numberToSquare)
{
    long y = SquareOf(numberToSquare);
    Console.WriteLine(y);
}

DoSomethingRad is clearly still pretty fail. But at least now we can pass in a number to square, so it won't write 16 every time. (It'll write 1, or 4, or 9, or 16, or... zzzz still kinda boring).

It'd be nice if there was a way to change what happens to the number passed in. Maybe we don't want to square it; maybe we want to cube it, or subtract it from 69 (number chosen at random from my head).

On further inspection, it seems as though the only part of SquareOf that DoSomethingRad cares about is that we can give it an integer (numberToSquare) and that it gives us a long (because we put its return value in y and y is a long).

public long CubeOf(int n)
{
    return n * n * n;
}

public void DoSomethingLeet(int numberToSquare)
{
    long y = CubeOf(numberToSquare);
    Console.WriteLine(y);
}

See how similar DoSomethingLeet is to DoSomethingRad? If only there was a way to pass in behavior (DoX()) instead of just data (int n)...

So now if we want to write a square of a number, we can DoSomethingRad and if we want to write the cube of a number, we can DoSomethingLeet. So if we want to write the number subtracted from 69, do we have to make another method, DoSomethingCool? No, because that takes too damn much typing (and more importantly, it hinders our ability to alter interesting behavior by changing only one aspect of our program).

So we arrive at:

public long Radlicious(int doSomethingToMe, Func<int, long> doSomething)
{
    long y = doSomething(doSomethingToMe);
    Console.WriteLine(y);
}

We can call this method by writing this:

Radlicious(77, SquareOf);

Func<int, long> is a special kind of delegate. It stores behavior that accepts integers and spits out longs. We're not sure what the method it points to is going to do with any given integer we pass; all we know is that, whatever happens, we are going to get a long back.

We don't have to give any parameters to SquareOf because Func<int, long> describes behavior, not data. Calling Radlicious(77, SquareOf) just gives Radlicious the general behavior of SquareOf ("I take a number and return its square"), not what SquareOf will do to any specific integer.

Now if you have understood what I am saying, then you have already one-upped me, for I myself don't really get this stuff.

* END ANSWER, BEGIN WANDERING IDIOCY *

I mean, it seems like ints could be perceived as just really boring behavior:

static int Nine()
{
    return 9;
}

That said, the line between what is data and behavior appears to blur, with what is normally perceived as data is simply boring-ass behavior.

Of course, one could imagine super "interesting" behavior, that takes all sorts of abstract parameters, but requires a ton of information to be able to call it. What if it required us to provide the source code that it would compile and run for us?

Well, then our abstraction seems to have gotten us all the way back to square one. We have behavior so abstract it requires the entire source code of our program to determine what it's going to do. This is fully indeterminate behavior: the function can do anything, but it has to be provided with everything to determine what it does. On the other hand, fully determinate behavior, such as Nine(), doesn't need any additional information, but can't do anything other than return 9.

So what? I don't know.

查看更多
forever°为你锁心
6楼-- · 2019-01-11 07:36

Like others have said, a delegate is a reference to a function. One of the more beneficial uses(IMO) is events. When you register an event you register a function for the event to invoke, and delegates are perfect for this task.

查看更多
Summer. ? 凉城
7楼-- · 2019-01-11 07:41

In the simplest possible terms, it's essentially a pointer to a method.

You can have a variable that holds a delegate type (just like you would have an int variable that can hold an int type). You can execute the method that the delegate points to by simply calling your variable like a function.

This allows you to have variable functions just like you might have variable data. Your object can accept delegates from other objects and call them, without having to define all the possible functions itself.

This comes in very handy when you want an object to do things based on user specified criteria. For example, filtering a list based on a user-defined true/false expression. You can let the user specify the delegate function to use as a filter to evaluate each list item against.

查看更多
登录 后发表回答