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