【问题标题】:How the delegates objects are created in c#? [duplicate]在 C# 中如何创建委托对象? [复制]
【发布时间】:2016-09-03 13:47:01
【问题描述】:

我刚开始学习 c# 中的委托。编译器遇到如下代码时如何创建委托对象

 delegate int Transformer (int x);
 Transformer t = new Transformer (Square);

我发现所有的委托都隐式地派生了 System.Delegate 类。 “new Transformer(Square)”会不会调用Delegate类的构造函数来创建名为't'的对象。

【问题讨论】:

    标签: c# delegates


    【解决方案1】:

    回顾 .net 框架 4.6.2 的 Roslyn 参考源 System.Delegate 类构造函数如下所示:

    [System.Security.SecuritySafeCritical]  // auto-generated
            protected Delegate(Object target,String method)
            {
                if (target == null)
                    throw new ArgumentNullException("target");
    
                if (method == null)
                    throw new ArgumentNullException("method");
                Contract.EndContractBlock();
    
                // This API existed in v1/v1.1 and only expected to create closed
                // instance delegates. Constrain the call to BindToMethodName to
                // such and don't allow relaxed signature matching (which could make
                // the choice of target method ambiguous) for backwards
                // compatibility. The name matching was case sensitive and we
                // preserve that as well.
                if (!BindToMethodName(target, (RuntimeType)target.GetType(), method,
                                      DelegateBindingFlags.InstanceMethodOnly |
                                      DelegateBindingFlags.ClosedDelegateOnly))
                    throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
            }
    
            // This constructor is called from a class to generate a 
            // delegate based upon a static method name and the Type object
            // for the class defining the method.
            [System.Security.SecuritySafeCritical]  // auto-generated
            protected unsafe Delegate(Type target,String method)
            {
                if (target == null)
                    throw new ArgumentNullException("target");
    
                if (target.IsGenericType && target.ContainsGenericParameters)
                    throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), "target");
    
                if (method == null)
                    throw new ArgumentNullException("method");
                Contract.EndContractBlock();
    
                RuntimeType rtTarget = target as RuntimeType;
                if (rtTarget == null)
                    throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "target");
    
                // This API existed in v1/v1.1 and only expected to create open
                // static delegates. Constrain the call to BindToMethodName to such
                // and don't allow relaxed signature matching (which could make the
                // choice of target method ambiguous) for backwards compatibility.
                // The name matching was case insensitive (no idea why this is
                // different from the constructor above) and we preserve that as
                // well.
                BindToMethodName(null, rtTarget, method,
                                 DelegateBindingFlags.StaticMethodOnly |
                                 DelegateBindingFlags.OpenDelegateOnly |
                                 DelegateBindingFlags.CaselessMatching);
            }
    

    所以,是的,您可以从那里的这个人那里获得派生类型。

    如果您正在寻找代表的基础知识:(我想我误读了这个问题,仍然保留在这里)

    委托声明的语法是

    delegate <return type> <delegate-name> <parameter list>
    

    From MSDN:

    委托是一种表示对具有特定参数列表和返回类型的方法的引用的类型。实例化委托时,可以将其实例与具有兼容签名和返回类型的任何方法相关联。您可以通过委托实例调用(或调用)该方法。

    因此,一旦声明了委托类型,就必须使用 new 关键字创建委托对象并与特定方法相关联。创建委托时,传递给新表达式的参数与方法调用类似,但没有方法的参数。

    public delegate void printStuff(string s);
    ...
    printStuff ps1 = new printStuff(WriteToScreen);
    printStuff ps2 = new printStuff(WriteToScreen);
    

    WriteToScreenWriteToScreen 实际上是在参数中带有字符串的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 2015-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 1970-01-01
      相关资源
      最近更新 更多