C#基本之匿名辦法實例教程。本站提示廣大學習愛好者:(C#基本之匿名辦法實例教程)文章只能為提供參考,不一定能成為您想要的結果。以下是C#基本之匿名辦法實例教程正文
本文以實例情勢講授了C#的匿名辦法的用法,分享給年夜家供年夜家參考之用。詳細以下:
匿名辦法是C# 2.0的說話新特征。起首看個最簡略的例子:
class Program { static void Main(string[] args) { List<string> names = new List<string>(); names.Add("Sunny Chen"); names.Add("Kitty Wang"); names.Add("Sunny Crystal"); List<string> found = names.FindAll( new Predicate<string>(NameMatches)); if (found != null) { foreach (string str in found) Console.WriteLine(str); } } static bool NameMatches(string name) { return name.StartsWith("sunny", StringComparison.OrdinalIgnoreCase); } }
這段代碼在開端的時刻初始化了一個字符串列表(string list),然後經由過程列表的FindAll辦法來查找以“sunny”肇端的字符串,最初將所查找到的一切成果輸入。
我們須要側重引見List<T>的FindAll辦法。這個辦法是一個參數為Predicate<T>類型、前往值為List<T>類型的函數。留意,Predicate<T>是一個泛型拜托,它指代如許一些函數:這些函數唯一一個T類型的參數,而且前往值是布爾類型。經由過程reflector等對象,我們可以看到Predicate<T>的界說以下:
public delegate bool Predicate<T>(T obj);
至此我們也若干可以或許猜到FindAll辦法的詳細完成。即針對List<T>中的每一個元素,挪用Predicate<T>所指代的函數,假如函數前往為true,則將其參加新建的列表中。遍歷完一切的元素後,將新建的列表前往給挪用者。以下:
public List<T> FindAll<T>(Predicate<T> match) { List<T> ret = new List<T>(); foreach (T elem in items) { if (match(elem)) ret.Add(elem); } return ret; }
是以,針對下面的例子,要挪用FindAll辦法,我們必需先界說一個參數為string類型,前往值為布爾類型的函數,在這個函數中,對參數停止前提斷定,假如相符前提(也就是以“sunny”作為肇端字符串),那末就前往true,不然前往false。最初再將這個函數作為參數傳遞給FindAll。因而也就獲得了最下面的代碼。
在下面的例子中,為了挪用FindAll辦法,我們不能不新界說一個函數,其實這個函數除FindAll辦法要用外,其余處所都簡直很少應用到它,你還不能不給它起個名字。假如法式中有多處須要挪用FindAll辦法,或許相似的情形,那末全部法式也就會湧現一年夜批“只要一個處所應用”的函數,使得代碼難於浏覽和保護。
因為存在如許的成績,C# 2.0引入了匿名辦法。開辟人員在完成辦法的時刻,只須要給出辦法的參數列表(乃至也能夠不給)和辦法詳細完成,而不須要關懷辦法的前往值,更不用給辦法起名字。最症結的是,只在須要的處所界說匿名辦法,包管了代碼的簡練。
匿名辦法只在須要的處所界說,界說的時刻,應用delegate症結字,後接參數列表,然後跟上用一對花括號包含起來的函數體便可。下面的代碼可以重組成上面的情勢:
class Program { static void Main(string[] args) { List<string> names = new List<string>(); names.Add("Sunny Chen"); names.Add("Kitty Wang"); names.Add("Sunny Crystal"); List<string> found = names.FindAll( delegate(string name) { return name.StartsWith("sunny", StringComparison.OrdinalIgnoreCase); }); if (found != null) { foreach (string str in found) Console.WriteLine(str); } } //static bool NameMatches(string name) //{ // return name.StartsWith("sunny", // StringComparison.OrdinalIgnoreCase); //} }
此時,我們完整不須要NameMatches辦法了,直接將匿名辦法作為參數傳遞給FindAll辦法。其實匿名辦法自己照樣著名字的,只是我們其實不關懷它畢竟該取甚麼名字,因此.NET幫我們隨意取了個名字而已。
匿名辦法在C#中運用非常普遍,由於拜托作為函數參數是件異常平凡的工作。在界說簡略的事宜處置進程時,我們異樣可使用匿名辦法。好比:
ServiceHost host = new ServiceHost(typeof(FileTransferImpl)); host.Opened += delegate(object sender, EventArgs e) { Console.WriteLine("Service Opened."); };
匿名辦法可以很便利地應用當地變量,這與零丁界說的定名辦法比擬,可以或許簡化編程。好比上文的例子中,假設Main函數外面界說了一個整型當地變量(部分變量)number,那末可以在delegate (string name)這一匿名辦法界說中應用number變量。
上文提到,在界說匿名辦法的時刻,連參數列表都可以省略。由於編譯器可以依據拜托的簽名來肯定函數的簽名,然後只需再給函數起個名字便可以了。上面的代碼演示了這類應用方法:
delegate void IntDelegate(int x); // 帶參數的界說方法 IntDelegate d2 = delegate(int p) { Console.WriteLine(p); }; // 不帶參數的界說方法(固然也沒帶前往值) IntDelegate d3 = delegate { Console.WriteLine("Hello."); };
在應用不帶參數和前往值的匿名辦法界說時,須要留意以下兩點:
1.假如在你的匿名辦法中須要對參數停止處置,那末你不克不及應用不界說參數列表的聲明方法。也就是在界說匿名辦法的時刻,須要給出參數列表。
2.不帶參數和前往值的匿名辦法,可以被具有任何情勢簽名的拜托所指代。
上述第一點不言而喻,由於你沒有界說參數列表,也就沒有方法應用參數;要解釋第二點,我們可以看上面的代碼:
class Program { delegate void IntDelegate(int x); delegate void StringDelegate(string y); static void Output(IntDelegate id) { } static void Output(StringDelegate sd) { } static void Main(string[] args) { /* * ERROR: The call is ambiguous between * Output(IntDelegate) * and * Output(StringDelegate) */ Output(delegate { }); } }
下面的代碼沒法編譯經由過程,由於編譯器不曉得應當將delegate { }這一匿名辦法復原為由IntDelegate指代的函數,照樣復原為由StringDelegate指代的函數。此時只能顯式給定參數列表,以便讓編譯器曉得,我們畢竟是想挪用哪一個Output函數。
願望本文所述對年夜家的C#法式設計有所贊助