代码之家  ›  专栏  ›  技术社区  ›  Keith Adler

有人能把代表的话提炼成恰当的英语吗?

  •  17
  • Keith Adler  · 技术社区  · 14 年前

    有人能把代表的职责分解成一个简单、简短、简洁的解释吗?这个解释既包含目的,也包含一般利益。我试着把我的头缠在这上面,但它没有陷进去。

    11 回复  |  直到 14 年前
        1
  •  21
  •   womp    14 年前

    用最简单的术语来说,它本质上是一个指向方法的指针。

    可以有一个包含委托类型的变量(就像有一个可以包含int类型的int变量一样)。通过像函数一样简单地调用变量,可以执行委托所指向的方法。

    这允许您拥有变量函数,就像您可能拥有变量数据一样。对象可以接受其他对象的委托并调用它们,而不必定义所有可能的函数本身。

    当您希望对象根据用户指定的条件执行操作时,这非常方便。例如,根据用户定义的真/假表达式筛选列表。您可以让用户指定委托函数,以用作评估每个列表项所依据的筛选器。

        2
  •  30
  •   xofz    14 年前

    我有一个功能:

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

    这个功能很糟糕。如果我想要3*3呢?

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

    打字太多了。我懒惰!

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

    我的 SquareOf 功能不在乎什么 n 是。对于任何 n 过去了。它不知道确切的数字 n 是,但是 知道 n 是一个整数。你不能通过 "Haha not an integer" 进入之内 方形的 .

    下面是另一个函数:

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

    与它的名字相反,dosomethingrad实际上并没有做任何rad的事情。然而,它确实写出了16的平方(4)。我们能把它改成不那么无聊吗?

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

    DoSomethingRad 显然还是很失败的。但至少现在我们可以把一个数传给平方,所以它不会每次写16。(它会写1,4,9,16,或者……还是有点无聊)。

    如果有办法改变传入的号码,那就太好了。也许我们不想把它平方;也许我们想把它平方,或者从69中减去它(从我的头脑中随机选择的数字)。

    经进一步检查,似乎 方形的 那个 多索明格勒 关心的是我们可以给它一个整数( numberToSquare )它给了我们 long (因为我们把它的回报值 y Y 是一个 长的 )

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

    看看有多相似 DoSomethingLeet 是为了 多索明格勒 ?要是有办法进去就好了 行为 ( DoX() )而不是仅仅 数据 ( int n )

    所以现在如果我们想写出一个数的平方,我们可以 多索明格勒 如果我们想写出一个数的立方,我们可以 剂量 . 如果我们想写出从69中减去的数字,我们需要另一种方法吗? DoSomethingCool ?不,因为这需要太多的输入(更重要的是,它只改变了程序的一个方面,从而妨碍了我们改变有趣行为的能力)。

    所以我们得出:

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

    我们可以通过编写以下命令来调用此方法:

    Radlicious(77, SquareOf);
    

    Func<int, long> 是一种特殊的代表。它存储接受整数并输出的行为 长的 我们不确定它所指向的方法对我们传递的任何给定整数会做什么;我们只知道,无论发生什么,我们都会得到 长的 回来。

    我们不需要给任何参数 方形的 因为 函数<int,long> 描写 行为 ,不是数据。打电话 Radlicious(77, SquareOf) 只是给了radlicous 方形的 (“我取一个数字并返回其平方”),而不是什么 方形的 对任何 具体的 整数。

    如果你明白我说的话,那么你已经有一个提升我,因为我自己并没有真正得到这些东西。

    *结束回答,开始胡思乱想*

    我是说,好像 int S可以被认为是非常无聊的行为:

    static int Nine()
    {
        return 9;
    }
    

    也就是说,什么是数据和行为之间的界限似乎模糊了,而通常被视为数据的只是无聊的屁股行为。

    当然,人们可以想象超级“有趣”的行为,它需要各种抽象参数,但需要大量信息才能调用它。如果它要求我们提供它将为我们编译和运行的源代码呢?

    好吧,那么我们的抽象似乎让我们回到了原点。我们有如此抽象的行为,它需要我们程序的整个源代码来决定它要做什么。这是完全不确定的行为:函数可以 任何东西 ,但必须提供 一切 以确定它的作用。另一方面,完全确定的行为,例如 Nine() ,不需要任何附加信息,但除了返回 9 .

    那又怎么样?我不知道。

        3
  •  3
  •   jim    14 年前

    委托是指向方法的指针。然后可以将委托用作其他方法的参数。

    here 是指向简单教程的链接。

    我的问题是‘那么,我为什么要这么做?’除非你用它们解决了编程问题,否则你不会真正“明白”。

        4
  •  3
  •   Duncan    14 年前

    有趣的是,没有人提到授权的一个关键好处——当你意识到继承不是一个灵丹妙药,通常会产生比它解决的问题更多的问题时,最好是进行子分类。它是许多设计模式的基础,尤其是 策略 模式。

        5
  •  2
  •   Andrew Hare    14 年前

    委托实例是对方法的引用。它们之所以有用,是因为您可以在类型的特定实例上创建绑定到特定方法的委托。委托实例允许您在特定实例上调用该方法,即使将要调用该方法的对象已离开词法范围。

    像这样的委托实例最常用的用法是支持 callbacks 在语言层面。

        6
  •  2
  •   Art W    14 年前

    它只是引用一个方法。它们在处理交叉线程时非常有用。

    下面是一个我代码中的例子。

     //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
    

    如果不使用委托,则无法跨线程调用lobby.adrotator函数。

        7
  •  1
  •   Bob    14 年前

    正如其他人所说,委托是对函数的引用。一个更有益的用途(imo)是事件。当您注册一个事件时,您注册了一个用于调用该事件的函数,并且委托非常适合此任务。

        8
  •  1
  •   Will Vousden    14 年前

    在最基本的术语中,委托只是包含(对)函数的引用的变量。委托很有用,因为它们允许您将函数作为变量传递,而不必关心函数的实际来源。

    当然,需要注意的是,当函数被绑定到变量中时,它不会被复制;它只是被引用绑定。例如:

    class Foo
    {
        public string Bar
        {
            get;
            set;
        }
    
        public void Baz()
        {
            Console.WriteLine(Bar);
        }
    }
    
    Foo foo = new Foo();
    Action someDelegate = foo.Baz;
    
    // Produces "Hello, world".
    foo.Bar = "Hello, world";
    someDelegate();
    
        9
  •  1
  •   AlwaysAProgrammer    14 年前

    最简单地说,执行一个方法的责任被委托给另一个对象。假设某个国家的总统去世了,美国总统应该带着慰问信出席葬礼。如果美国总统不能去,他将把这个责任委托给副总统或国务卿。

    代码也一样。委托是一种类型,它是能够执行该方法的对象。

    如。

    Class Person
    {
       public string GetPersonName(Person person)
       {
         return person.FirstName + person.LastName;
       }
    
       //Calling the method without the use of delegate
       public void PrintName()
       {
          Console.WriteLine(GetPersonName(this));
       }
    
       //using delegate
       //Declare delegate which matches the methods signature
       public delegate string personNameDelegate(Person person);
    
      public void PrintNameUsingDelegate()
      {
          //instantiate
          personNameDelegate = new personNameDelegate(GetPersonName);
    
          //invoke
          personNameDelegate(this);
      }
    
    }
    

    getPersonName方法是使用委托对象personnameDelegate调用的。 或者,我们可以使用printnameousingdelegate方法将委托作为参数。

    public void PrintNameUsingDelegate(personNameDelegate pnd, Person person)
    {
       pnd(person);
    }
    

    这样做的好处是,如果有人想将名称打印为lastname_firstname,他/她只需将该方法包装在personnamedelement中并传递给此函数。无需进一步更改代码。

    代表在

    1. 事件
    2. 异步调用
    3. LINQ(作为lambda表达式)
        10
  •  0
  •   Edwin Buck    14 年前

    如果要将任务委派给某人,则该委派将是接收该工作的人。

    在编程中,它是对代码块的引用,而代码块实际上知道如何做某事。通常这是指向将处理某些项的函数或方法的指针。

        11
  •  0
  •   Andrew Kosta    14 年前

    用我能想到的最简单的话来说就是:一个委托将把工作的负担强加给一个几乎知道该怎么做的类。把它想象成一个孩子,他不想完全像他哥哥那样长大,但仍然需要他的指导和命令。他没有从哥哥那里继承所有的方法(即子类化),而是让弟弟做这项工作,或者让弟弟做一些需要哥哥采取行动的事情。当你陷入协议的行列时,老大哥会定义什么是绝对需要的,或者他可能会给你灵活性,让你在某些事件中选择你想让他做的事情(如objective-c中概述的非正式和正式协议)。

    这个概念的绝对好处是您不需要创建子类。如果你想让某件事顺理成章,那么当一个事件发生时,遵循命令,委托允许一个开发的类握住它的手,并在必要时发出命令。