Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确使用学员/了解学员_C#_Visual Studio_Delegates_Event Handling - Fatal编程技术网

C# 如何正确使用学员/了解学员

C# 如何正确使用学员/了解学员,c#,visual-studio,delegates,event-handling,C#,Visual Studio,Delegates,Event Handling,使用-C#(.NETFramework 4.5,VisualStudio2012) 我试图理解像“代表”这样的主题,目前我有几点需要澄清。 我在互联网上找到了很多描述如何使用它的不同信息,但对我来说理解这个主题有点复杂 据我所知,我必须为使用委托做几件事: 创建一些实体以使用它(需要创建一些委托) 声明委托类型 创建一些方法,我在其中调用委托 在主类中使用使用实体的必需方法调用委托(从第一点开始) 我将在下面展示所有描述 问题-我是否正确理解了所有内容,或者可能我错了-请澄清 还有另一个关

使用-C#(.NETFramework 4.5,VisualStudio2012)

我试图理解像“代表”这样的主题,目前我有几点需要澄清。 我在互联网上找到了很多描述如何使用它的不同信息,但对我来说理解这个主题有点复杂

据我所知,我必须为使用委托做几件事:

  • 创建一些实体以使用它(需要创建一些委托)
  • 声明委托类型
  • 创建一些方法,我在其中调用委托
  • 在主类中使用使用实体的必需方法调用委托(从第一点开始)
我将在下面展示所有描述

问题-我是否正确理解了所有内容,或者可能我错了-请澄清

还有另一个关于委托的问题在控制台C#应用程序中,将代码与委托放在哪里更好?我可以在使用名称空间的任何位置创建它,如下所示

但可能有一些建议/要求,不仅用于控制台应用程序,而且用于WinForms、WPF等

这个主题对我来说是新的,我花了一天的时间来理解它,但仍然有点(或更多)对此感到困惑,最后创建这个帖子以更好、更清晰地理解它。我觉得这是很有力量的东西

编辑

namespace SimpleCSharpApp
{
   delegate void myDelagate ();
}
< C >中的委托有点像C++中的函数指针的替换。它们有很多用途。您可以使用它们来:

  • 装箱事件的内联实现
  • 将回调传递给函数
  • 创建一个可以在循环中调用的“函数”数组
  • 根据我的经验,第一种用法是最常见的

    Button.Click += delegate(object sender, EventArgs args)  => {/*you do something here*/};
    
    可通过lamba表达式进行简化:

    Button.Click += (sender, args) => {/*you do something here*/};
    
    您可以为按钮单击提供一些行为,而不必为其创建单独的方法


    关于你问题的第二部分,我通常将代表声明放在单独的文件中。

    呵呵。。你把事情搞砸了。直到我看到VS在“委托”声明下带有红色下划线的屏幕截图,我才完全理解您试图陈述的问题

    首先,暂时忘掉
    public void委托zcxxzc
    行。这有点特别。首先,让我们看看一些标准类型的代理

    最基本的两个方面是:

    • System.Action
    • System.Func
    两者都是通用的,第一次看到它们的签名,它们可能看起来过于复杂。但是,它们真的很简单

    首先,让我们限制为裸的、无参数的、
    System.Action

    private static void myFunction1() { Console.WriteLine("Hello!"); }
    private static void myFunction2() { Console.WriteLine("Bye!"); }
    private static void myFunction0() { return; }
    
    ... // in some function, i.e. Main()
    Action myDelegate = null;
    
    myDelegate = new Action( myFunction1 );
    myDelegate(); // writes "Hello!"
    
    myDelegate = new Action( myFunction2 );
    myDelegate(); // writes "Bye!"
    
    myDelegate = new Action( myFunction3 );
    myDelegate(); // does "nothing"
    
    就像“int”保存数字,“string”-文本一样,“delegate”保存关于“可调用的东西”的信息,或者用一些术语来说,“可调用的东西”

    首先,我创建一个类型为“Action”的委托,该委托记住“myFunction1”。然后我调用/调用该委托-它会导致调用记住的函数

    然后,我创建一个类型为“Action”的委托,该委托记住“myFunction2”。然后我调用/调用该委托-它会导致调用记住的函数

    最后,我创建了一个类型为“Action”的委托,它记住了“myFunction3”。然后我调用/调用该委托-它会导致调用记住的函数,而不会发生任何事情-但这只是因为目标函数没有做任何事情

    请注意,我特意说“创建了一个委托”。每次执行
    新操作
    ,都会创建一个新委托。“委托”只是一个对象,就像字符串“foo”或float[]{1.2,4.5}

    另外,请注意,这里使用的创建委托的完整语法是
    newaction(…)
    。就像创建任何对象一样-新建+类型名+构造参数。“委托”只是一个对象的另一个标志

    另外需要注意的是,我没有编写
    新操作(myFunction1())
    。我不想调用该方法并获得其结果,然后将该结果交给Action的构造函数。我写了
    新动作(myFunction1)
    。我把函数本身给了构造函数

    那么,什么是“行动”?行动是一门课。比如字符串、套接字或WebClient。这里没什么特别的。因此,我们有一个“类”,它的对象可以记住应该调用什么函数。酷

    因此,有些人将委托与“函数指针”相比较。但这并不完全正确。函数指针可以记住要调用的函数。学员可以记住要调用的方法。还记得区别吗?在上面的示例中,我特意在每个
    myFunction
    中编写了
    static
    。这些可以称为无对象/无目标。你只需要知道他们的名字,你可以在任何地方给他们打电话。要调用它们,一个简单的哑指针就足够了

    现在,代表们可以做得更多。他们可以使用方法。但是需要对对象调用方法

    class GuineaPig
    {
        public static void Squeak() { Console.WriteLine("Ieek!"); }
    
        public void Well() { Console.WriteLine("actually"); }
        public void IDontKnow() { Console.WriteLine("what they do"); }
    }
    
    GuineaPig.Squeak(); // says 'ieek'
    
    Action myDelegate = null;
    myDelegate = new Action( GuineaPig.Squeak );
    myDelegate(); // writes "ieek"
    
    // GuineaPig.Well(); // cannot do!
    // myDelegate = new Action( GuineaPig.Well ); // cannot do!
    
    好的,在另一个类中委托一个静态函数是很容易的——只需要准确地说出来自哪个类的函数。再次,就像呼叫一样,但没有括号

    但是,如果尝试取消对非静态方法的引用的注释,它将无法编译。看看
    guineappig.嗯
    ——这是显而易见的。它不是静态的,需要针对对象而不是类调用它。出于同样的原因,无法创建委托。让我们解决这个问题:

    class GuineaPig
    {
        public void Well() { Console.WriteLine("actually"); }
        public void IDontKnow() { Console.WriteLine("what they do"); }
    }
    
    GuineaPig myPiggie = new GuineaPig();
    
    myPiggie.Well(); // ok! writes "actually"
    
    Action myDelegate = null;
    myDelegate = new Action( myPiggie.Well ); // ok!
    
    myDelegate(); // ok! writes "actually".
    
    请注意,在创建委托期间,classname是如何被objectvariable替换的。语法被保留:就像调用一样,但没有paren。但是,“方法”和“函数”到底有什么区别呢

    委托不仅可以存储要调用的“what method”,还可以存储what objec
    class GuineaPig
    {
        public string Name;
    
        public void Well() { Console.WriteLine("I'm " + Name); }
    }
    
    GuineaPig myPiggie1 = new GuineaPig { Name = "Bubba" };
    GuineaPig myPiggie2 = new GuineaPig { Name = "Lassie" };
    
    Action myDelegate = null;
    
    myDelegate = new Action( myPiggie1.Well );
    myDelegate(); // -> Bubba
    
    myDelegate = new Action( myPiggie2.Well );
    myDelegate(); // -> Lassie
    
    myPiggie1 = myPiggie2 = null;
    
    myDelegate(); // -> Lassie
    
    class MyStudentFilteringDelegate
    {
         public object Target;
         public somethingstrange*  MethodPointer;
    
         // other code
    }
    
    MyDelegate dd = new MyDelegate ( ... );
    dd(); // is just impossible!!!
    
    public bool delegate MyStudentFilteringDelegate( Student stud );
    
    public class MyStudentFilteringDelegate : some_framework_Delegate_class
    {
        // object Target {get;} - inherited from base class
        // MethodInfo Method {get;} - inherited from base class, too
    }
    
    var dd = new MyStudentFilteringDelegate ( ... ); // like normal class!
    dd(); // ok!;
    
    public bool delegate MyStudentFilteringDelegate( Student stud );
    
    public class Xc {}
    public void delegate Xd();
    
    namespace WTF {
        public class Xc {}
        public void delegate Xd();
    
        class Whatever {
            public class Xc {}
            public void delegate Xd();
        }
    }
    
    namespace MyNamespace {
       public delegate void SpecialEventDelegate(object sender, CustomEventArgs e);
    
       public class CustomEventArgs : EventArgs {
          // implementation details
       }
    }
    
       public delegate void SpecialEventDelegate(object sender, CustomEventArgs e);
    
       Action<object, CustomEventArgs> // similar declaration to the SpecialEventDelegate above
    
       Func<bool> // a delegate that return true/false
    
    namespace MyNamespace {
    
       public delegate Stream OpenFile(FileInfo FileSpec);
    
    }
    
    class XMLHandler : IFileHandler {
    
       private OpenFile xmlFileReader;
    
       // implementation of interface
       public OpenFile FileHandler {
          get { return xmlFileReader; }
       }
    
       public XMLHandler(){
          xmlFileReader = MyXmlFileReader;  // references the private method in this class
       }
    
       private Stream MyXmlFileReader(FileInfo XmlFileSpec) {
          // implementation specific to this class
       }
    
    }
    
    interface IFileHandler {
    
       OpenFile FileHandler { get; }
    
    }