代码之家  ›  专栏  ›  技术社区  ›  StuartLC

为什么委托可以互换地用于类方法和静态函数?

  •  3
  • StuartLC  · 技术社区  · 14 年前

    我已经使用代表很多年了,并没有给他们太多的思考。 但最近我认为代表们包括 this 引用类方法时在签名中引用。 下面的例子说明了我理解中的差距。

    public class SomeClass
    {
        public SomeClass(int someProperty)
        {
            SomeProperty = someProperty;
        }
    
        public int SomeProperty
        { 
            get; 
            set; 
        }
    
        // Throw in a Member field into the mix
        public int ClassAdd(int x, int y)
        {
            return x + y + SomeProperty;
        }
    }
    
    public static class SomeStaticClass
    {
        public static int StaticAdd(int x, int y)
        {
            return x + y;
        }
    }
    

    为什么我可以同时添加静态订阅服务器和实例订阅服务器?

        delegate int addDelegate(int x, int y);
    
        class TestClass
        {
            delegate int addDelegate(int x, int y);
    
            private void useDelegates()
            {
                addDelegate algorithm;
                algorithm = SomeStaticClass.StaticAdd;
                algorithm += new SomeClass(3).ClassAdd;
    
                int answer = algorithm(5, 10);
            }
        }
    

    什么 真的要继续吗?;)

    3 回复  |  直到 10 年前
        1
  •  4
  •   Jon Skeet    14 年前

    如果创建一个引用实例方法的委托,它将捕获 this (或相关参考资料)支持 Target 委托的属性。如果创建引用静态方法的委托,则 靶标 将为空。在逻辑上,如果您使用的是静态方法,就不需要有实例。

    作为一个额外的复杂因素,你可以 延伸 方法,就好像它们是扩展类型上的实例方法一样:

    static class Extensions
    {
        public static void Foo(this string x)
        {
            Console.WriteLine("Calling Foo on " + x);
        }
    }
    
    class Test
    {
        static void Main()
        {
            Action action = "text".Foo;
            Console.WriteLine(action.Target); // Prints "text"
        }
    }
    

    至于 为什么 你可以这样做:因为它很有用,而且没有理由 允许你这样做:)

        2
  •  1
  •   Andrey    14 年前

    C中没有静态函数,它们实际上是静态方法(因此有静态方法和实例方法)。每个委托基本上都是指向方法和 this 将在其上执行方法的指针,它是 Target 委托的属性。对于静态方法,它将为空。因为委托携带对对象的引用,所以如果忘记取消订阅,它可能会导致内存泄漏。

        3
  •  1
  •   tdammers    14 年前

    委托的好处在于它们只对静态方法和实例方法起作用。如果将静态方法分配给委托,静态方法将简单地按原样使用,因为它不需要任何非静态上下文来工作。例如,对实例的引用存储在方法指针上,以便 this 引用)在调用方法时可用。这意味着,当您将实例方法分配给委托时,还必须提供一个实例—通过显式地指定它,或者从实例上下文中分配给委托。

    大多数时候,这“只是有效的”,你不需要考虑任何事情。但是有一个警告:如果将实例方法分配给委托,则创建对该实例的另一个引用,并且只要该方法仍然分配给委托(或订阅了一个事件),则还会有对该实例的引用,因此GC将永远不会收集该实例。这就是为什么你在清理完自己之后,应该总是取消订阅所有事件的原因。