如何在c#中创建委托对象?

时间:2016-09-03 13:47:01

标签: c# delegates

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

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

我发现所有委托都隐式派生出System.Delegate类。将是"新变压器(Square)"调用Delegate类的构造函数来创建名为' t'。

的对象

1 个答案:

答案 0 :(得分:0)

回顾.net框架的Roslyn参考源4.6.2 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这里实际上是params中包含字符串的方法。