你所不知道的linq


  • 問題的提出

昨天在qq群問了一個linq的問題被人鄙視了。題目大概類似於 

 var reuslt=from s in new List<string>() select s;

from...in...select...中in后面如果接的不是集合,而是一個delegate,會怎么樣??之后就被人鄙視了,一些人嘲笑我工作年頭是混出來的,in后面當然是數據源了,delegate也可以作為數據源,所以當然可以了。無奈,只能百度——在微軟的官網上查到了如下信息:

!!!!!!!!!我的親娘啊,我現在的代碼中from in select 子句的in后面已經跟了delegate,並且是可行的。難道delegate繼承自IEnumerable??

打死也不信。微軟官網在說謊。那真實的情況是什么樣的呢,后來我終於在源碼中找到了一個自認為合理的解釋,或許這就是from in select 子句的本質,現在分享給大家,如果事實不是這樣,歡迎指正。

  • 問題的本質

from in select子句肯定會編譯成c#代碼的,會編譯成什么呢?我的猜測是這個子句的三個關鍵字會一起編譯。后來結合源碼,分析到其實只要in后面的數據類型Tin實現擴展方法

 public static T3 Select<T1, T2,T3>(this Tin tin, Func<T1, T2> selector)

只要實現這個擴展方法,T2類型就可以放到in后面作為數據源。而T1類型就是from子句對象的類型,而select子句的lambda表達式對應的就是Func<T1,T2>selector.

select子句的類型和lambda表達式的入參是一致的。而select返回的類型,不一定是最終返回的類型,而Select擴展方法的返回值會作為最終的返回類型。

多說也不明白,還是給大家上示例代碼,一看就明白了。

    class Program
    {
        static void Main(string[] args)
        {
            var result = from s in new TestApp() { A = 2 } select s;
            Console.WriteLine(result.GetType() + " " + result);
            Console.ReadLine();

            var reuslt = from s in new List<string>() select s;
        }
    }
    public class TestApp
    {
        public int A { get; set; }
    }
    public static class SelectExtension
    {
        public static string Select(this TestApp app, Func<int, int> selector)
        {
            return "hello,你是" + selector(app.A).ToString();
        }
    }
  •   最后的心得

1,qq群很少能夠幫上你忙得,官方文檔也是不可靠的。

2,常識很可能是假的

3,有空還是多看看開源代碼,那是真的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM