การใช้งาน LINQ และ Lambda Expressions นำไปสู่รหัสที่อ่านได้น้อยลงหรือไม่ [ปิด]


43

ฉันกำลังพูดคุยกับเพื่อนร่วมงานใน Linq ฉันจะคัดลอกที่นี่:

ผู้ร่วมงาน: ขอซื่อสัตย์ที่นี่ ไวยากรณ์ Linq แย่มาก มันสับสนและไม่ง่าย

ฉัน: โอ้มาเลยสับสนมากกว่า T-SQL เหรอ?

เพื่อนร่วมงาน: เอ่อใช่

ฉัน: มันมีส่วนพื้นฐานเดียวกันเลือกสถานที่และจาก

ผู้ร่วมงาน: Linq สำหรับฉันคือการกำจัดไอเท็มเชิงสัมพันธ์ + OO ผู้ร่วมงาน: อย่าเข้าใจฉันผิด - มันมีประสิทธิภาพอย่างไม่น่าเชื่อ แต่พวกเขาเรียกคืน SQL เพื่อใช้การเก็บรวบรวมวัตถุ agains

ฉันเห็นว่าการใช้ Linq + Lamda นั้นทรงพลังมาก (เขาเห็นด้วย) และทำให้อ่านรหัสได้ง่ายขึ้น (เขาไม่เห็นด้วยกับจุดนั้น):

pickFiles = from f in pickFolder.GetFiles("*.txt")
where ValidAuditFileName.IsMatch(f.Name)
select f;

หรือ

var existing = from s in ActiveRecordLinq.AsQueryable<ScannedEntity>()
where s.FileName == f.FullName && s.DocumentType != "Unknown"
select s;

หรือ (รหัส VB ​​ที่นี่)

   Dim notVerified = From image In images.AsParallel
     Group Join verifyFile In verifyFolder.GetFiles("*.vfy").AsParallel.Where(
      Function(v) v.Length > 0
      ).AsParallel
   On image.Name.Replace(image.Extension, ".vfy") Equals verifyFile.Name
     Into verifyList = Group
    From verify In verifyList.DefaultIfEmpty
    Where verify Is Nothing
    Select verify

สำหรับฉันนี่สะอาดและง่าย (อย่างน้อยง่ายกว่าทางเลือก) ในการอ่านคุณมีความคิดเห็นอย่างไรกับมัน?


11
มนุษย์โดยทั่วไปเกลียดการเปลี่ยนแปลง ร้อยละมากเกลียดมากจนพวกเขากลัว
Tony

9
ลองดูสิ ... linq เป็นเพียงแค่ซินแท็กซ์ไวยากรณ์การเขียนโปรแกรมที่ใช้งานได้เพิ่มลงใน C # และ VB.Net การทุบลินุกและแลมบ์ดาเป็นการแสดงออกโดยทั่วไปว่า "FP sucks" นั่นคือสิ่งที่เพื่อนร่วมงานของคุณกำลังพูด ฉันคิดว่าการโต้วาทีถูกแฮ็กที่อื่น
Scott Whitlock

48
มันรบกวนคนอื่นที่คนมักจะใช้คำว่า "สัญชาตญาณ" เมื่อพวกเขาหมายถึง "คุ้นเคย" หรือไม่?
Larry Coleman

7
อย่างไรก็ตามทีม C # (รวมถึง Eric Lippert) ได้ออกไปอธิบายว่า Linq ไม่ใช่การย้ายของ SQL แต่ได้รับการออกแบบมาจากพื้นฐานเหมือนคุณสมบัติอื่น ๆ ส่วนใหญ่ ฉันต้องบอกว่าเพื่อนร่วมงานของคุณคือ Luddite
Aaronaught

16
สำหรับสิ่งที่คุ้มค่า: ฉันเพิ่งมีภรรยา (ผู้ดูแลสำนักงาน - ติดกับศูนย์ประสบการณ์การเขียนโปรแกรมในทางปฏิบัติ) ของฉันดูที่ aaronaught 3 ตัวอย่างและก็สามารถที่จะถอดรหัสเจตนาของ LINQ และแลมบ์ดาตัวอย่างไกลได้ง่ายกว่าตัวอย่างความจำเป็นแบบดั้งเดิม
Steven Evers

คำตอบ:


73

ฉันไม่สามารถหาโพสต์ที่ถูกต้องอีกต่อไป แต่เอริค Lippert (และ softies อื่น ๆ อาจจะหลาย ๆ คน) ได้เห็นหลายต่อหลายครั้งเกี่ยวกับวิธี Linq เป็นที่เปิดเผยซึ่งหลายชั้นเรียนของปัญหาอยู่ไกลที่ใช้งานง่ายกว่าความจำเป็นไวยากรณ์

Linq ช่วยให้คุณสามารถเขียนโค้ดที่เป็นการแสดงออกถึงความตั้งใจที่จะไม่กลไก

คุณบอกฉันว่าอ่านง่ายกว่า นี้:

IEnumerable<Customer> GetVipCustomers(IEnumerable<Customer> source)
{
    List<Customer> results = new List<Customer>();
    foreach (Customer c in source)
    {
        if (c.FirstName == "Aaron")
        {
            results.Add(c);
        }
    }
    results.Sort(new LastNameComparer());
    return results;
}

class LastNameComparer : IComparer<Customer>
{
    public int Compare(Customer a, Customer b)
    {
        return x.LastName.CompareTo(b.LastName);
    }
}

หรือสิ่งนี้

IEnumerable<Customer> GetVipCustomers(IEnumerable<Customer> source)
{
    return from c in source
           where c.FirstName == "Aaron"
           orderby c.LastName
           select c;
}

หรือแม้แต่สิ่งนี้

IEnumerable<Customer> GetVipCustomers(IEnumerable<Customer> source)
{
    return source.Where(c => c.FirstName == "Aaron").OrderBy(c => c.LastName);
}

ตัวอย่างแรกเป็นเพียงกลุ่มของหม้อไอน้ำแบบไม่มีจุดหมายเพื่อให้ได้ผลลัพธ์ที่ง่ายที่สุด ใครที่คิดว่ามันเป็นมากขึ้นอ่านกว่ารุ่นความต้องการ Linq จะมีหัวของเขาตรวจสอบ ไม่เพียงแค่นั้น แต่คนแรกเสียความทรงจำ คุณไม่สามารถแม้แต่จะเขียนโดยใช้yield returnเพราะการเรียงลำดับ

เพื่อนร่วมงานของคุณสามารถพูดในสิ่งที่เขาต้องการได้ ส่วนตัวแล้วฉันคิดว่า Linq ได้ปรับปรุงการอ่านรหัสของฉันอย่างมากมาย

ไม่มีอะไรที่เกี่ยวกับ Linq มันอาจมีความคล้ายคลึงกันบางอย่างกับ SQL แต่ไม่ได้พยายามในรูปร่างหรือรูปแบบใด ๆ ที่จะใช้แคลคูลัสเชิงสัมพันธ์ เป็นเพียงส่วนขยายที่ช่วยให้ค้นหาและเรียงลำดับโครงการได้ง่ายขึ้น "Query" ไม่ได้หมายถึง "relational" และในความเป็นจริงแล้วมีหลายฐานข้อมูลที่ไม่ใช่เชิงสัมพันธ์ที่ใช้ไวยากรณ์คล้าย SQL Linq เป็นอย่างหมดจดเชิงวัตถุมันก็เกิดขึ้นกับการทำงานร่วมกับฐานข้อมูลเชิงสัมพันธ์ผ่านกรอบเช่น Linq เพื่อ SQL เพราะบางวูดูต้นไม้แสดงออกและการออกแบบที่ชาญฉลาดจากทีมงาน C # ทำให้ฟังก์ชั่นที่ไม่ระบุชื่อโดยปริยายแปลงสภาพให้แก่ต้นไม้แสดงออก


6
+1 ถ้าคุณไม่ชอบ LINQ อาจเป็นเพราะ "คุณไม่ได้ทำถูกต้อง" :)
Darknight

1
Linq is purely object-oriented+1 สำหรับสิ่งนี้ นี่คือสาเหตุที่คู่มือสไตล์ทีมของเราบังคับใช้โดยใช้ไวยากรณ์ได้อย่างคล่องแคล่วเหนือไวยากรณ์คิวรี ฉันพบว่าทำให้ลักษณะของการเชื่อมโยง OO ชัดเจนมากขึ้นกับบางคนที่ใช้ในการคัดค้านสัญกรณ์ในภาษา C-like
SBI

1
ฉันรู้ว่าโพสต์คือ 7 ปี แต่นี่คือคำถาม: คุณใช้ภาษาทำงานเป็นเครื่องมือหลักในการประชุม Linq หรือไม่?
Sergey.quixoticaxis.Ivanov

4
ค่อนข้างตรงไปตรงมาฉันชอบ foor loop เพราะฉันเห็นทันทีที่เราสามารถและจะมีข้อยกเว้นอ้างอิง NULL วิธีการจัดการเป็นโมฆะและมันไม่ได้ดำเนินการรอการตัดบัญชีซึ่งทำให้การแก้จุดบกพร่องยากและไม่สร้างรายการ n เช่นกันดังนั้น for-loop ก็มีประสิทธิภาพมากขึ้นเช่นกัน
แน่ใจ

1
@Aaraught หากคุณลบการเรียงลำดับและฟอร์แมตโค้ดโพรซีเดอร์ในสไตล์ Horstmannฉันจะบอกว่ามันอ่านได้ง่ายกว่ารุ่นLINQ และตามหลักการของความรับผิดชอบเดี่ยวการเรียงลำดับไม่ได้อยู่ในความจริงGetVipCustomers()ซึ่งตามชื่อของมันบ่งบอกว่าจะส่งคืนคอลเลกชันของลูกค้าวีไอพีเท่านั้นตามลำดับโดยพลการ สำหรับกรณีที่ไม่ค่อยเกิดขึ้นซึ่งคำสั่งนั้นสำคัญเช่นเอาท์พุทไปยังหน้าจอให้ผู้เรียกจัดเรียงคอลเลกชัน
Ant_222

69

ผู้ร่วมงาน: ขอซื่อสัตย์ที่นี่ ไวยากรณ์ Linq แย่มาก มันสับสนและไม่ง่าย

คุณไม่สามารถโต้เถียงกับคำวิจารณ์นั้นได้ สำหรับเพื่อนร่วมงานของคุณมันแย่มาก เราไม่สามารถออกแบบไวยากรณ์ที่ชัดเจนและใช้งานง่ายสำหรับพวกเขา นั่นคือความล้มเหลวของเราและคุณสามารถส่งคำขอโทษของฉันไปยังเพื่อนร่วมงานของคุณ ฉันยินดีที่จะให้คำแนะนำในการทำให้ดีขึ้น เพื่อนร่วมงานของคุณพบสิ่งใดเป็นพิเศษทำให้เกิดความสับสนหรือไม่เข้าใจง่าย

อย่างไรก็ตามคุณไม่สามารถทำให้ทุกคนพอใจได้ ความเห็นส่วนตัวของฉันและความเห็นของคนส่วนใหญ่ที่ฉันได้พูดคุยในเรื่องนี้ก็คือไวยากรณ์ของความเข้าใจในการสืบค้นนั้นชัดเจนกว่าไวยากรณ์ที่จำเป็นเทียบเท่า เห็นได้ชัดว่าไม่ใช่ทุกคนที่เห็นด้วย แต่โชคดีที่เราไม่ต้องการความเห็นเป็นเอกฉันท์จากลูกค้าหลายล้านคนของเราเมื่อเราออกแบบภาษา

ในเรื่องของ "สัญชาตญาณ" แม้ว่าฉันจะนึกถึงเรื่องราวของนักภาษาศาสตร์ชาวอังกฤษที่ศึกษาภาษาต่าง ๆ มากมายและในที่สุดก็ได้ข้อสรุปว่าภาษาอังกฤษเป็นภาษาที่ดีที่สุดของทุกภาษาเพราะในภาษาอังกฤษคำมาในลำดับเดียวกันกับคุณ พวกเขาคิดว่า ต่างจากชาวฝรั่งเศสที่พวกเขาพูดอย่างต่อเนื่องเช่น "สุนัขสีขาวกินเนื้อแดง" มันยากแค่ไหนที่คนฝรั่งเศสต้องคิดคำในลำดับที่ถูกต้องแล้วต้องพูดตามลำดับภาษาฝรั่งเศส ! ฝรั่งเศสใช้งานง่ายมาก! มันวิเศษมากที่คนฝรั่งเศสพูดได้ แล้วภาษาเยอรมันเหรอ? พวกเขาคิดว่า "สุนัขกินเนื้อ" แต่ต้องพูดว่า "สุนัขกินเนื้อ"!?!

บ่อยครั้งที่สิ่งที่ "ใช้งานง่าย" เป็นเพียงเรื่องของความคุ้นเคย ฉันใช้เวลาทำงานกับ LINQ หลายเดือนก่อนที่ฉันจะหยุดการสืบค้นด้วยประโยค "select" ตอนนี้มันเป็นลักษณะที่สองและคำสั่ง SQL ดูเหมือนแปลกประหลาด

ซึ่งมันคือ! กฎการกำหนดขอบเขตทั้งหมดนั้นเกิดความสับสนใน SQL สิ่งที่คุณอาจต้องการชี้ให้เห็นถึงผู้ร่วมงานคือ LINQ ได้รับการออกแบบอย่างระมัดระวังเพื่อให้ (1) การแนะนำตัวแปรและขอบเขตเกิดขึ้นจากซ้ายไปขวา (*) และ (2) ลำดับที่แบบสอบถามปรากฏบนหน้าคือ คำสั่งที่จะถูกดำเนินการ นั่นคือเมื่อคุณพูด

from c in customers where c.City == "London" select c.Name

c จะปรากฏในขอบเขตทางด้านซ้ายและอยู่ในขอบเขตผ่านทางด้านขวา และลำดับของสิ่งต่าง ๆ ที่เกิดขึ้นคือ "ลูกค้า" คนแรกที่ถูกประเมิน จากนั้นจะทำการประเมิน "where" เพื่อกรองลำดับ จากนั้นลำดับการกรองจะถูกฉายโดย "เลือก"

SQL ไม่มีคุณสมบัตินี้ ถ้าคุณพูด

SELECT Name FROM Customers WHERE City = 'London'

จากนั้น "ชื่อ" จะถูกนำเข้ามาในขอบเขตโดยบางสิ่งทางด้านขวาไม่ใช่ทางซ้ายและแบบสอบถามจะถูกดำเนินการในลำดับที่ยุ่งเหยิงอย่างสมบูรณ์ ประโยคกลางจะถูกประเมินก่อนจากนั้นประโยคสุดท้ายและจากนั้นประโยคแรก ตอนนี้ดูเหมือนว่าจะบ้าและไม่ได้ใช้งานง่ายสำหรับฉันทำงานกับ LINQ มานานแล้ว


(*) กฎการกำหนดขอบเขตค่อนข้างแปลกใน LINQ พร้อมกับส่วนคำสั่ง แต่นอกเหนือจากนั้นขอบเขตรังอย่างดี


5
nitpick: ในเยอรมัน "Der Hund frisst das Fleisch" เป็นจริงการสั่งซื้อเช่นเดียวกับในภาษาอังกฤษว่า "สุนัขกินเนื้อสัตว์" :) นอกเหนือจากที่ผมพบว่า LINQ แบบสอบถามไวยากรณ์อ่านได้มากเมื่อฉันรู้ว่ามันไม่ได้เป็น SQL
Michael Stum

18
@gbjbaanb: ผมไม่ได้แสดงเหตุผลอันสมควรไวยากรณ์ LINQ บนพื้นฐานอัตนัยทั้งหมดของมันถูกเข้าใจมากขึ้น แต่ฉันให้เหตุผลตามวัตถุประสงค์ทั้งหมดว่ามันง่ายกว่าการออกแบบเครื่องมือที่ช่วยผู้ใช้ในการสร้างการสืบค้น LINQ เพราะไวยากรณ์ LINQ ได้รับการออกแบบด้วยเครื่องมือในใจและง่ายต่อการเข้าใจทางจิตใจ ลำดับเหตุการณ์ที่เกิดขึ้นในแบบสอบถามเนื่องจากเหตุการณ์เหล่านั้นเรียงตามลำดับเดียวกัน
Eric Lippert

2
เอริคจากมุมมองการเขียนโปรแกรมของรูปแบบการประกาศฉันเข้าใจว่า Linq เหมาะสม (ฉันต้องพูดว่าอ่านได้) กว่า SQL แต่มันเป็นมนุษย์อ่านได้มากกว่า SQL? ไม่มีทาง. ถ้า 'สุนัขกินเนื้อแดง' จะยากแค่ไหน 'ครัวจากที่มีสีแดงมีด' ในความเป็นจริงเราทุกคนพูดและคิดเหมือน 'เอามีดที่อยู่ด้านบนของโต๊ะออกมาจากครัว' และนั่นคือที่ซึ่ง SQL ใกล้เคียงกับชีวิตจริงมากกว่า LINQ
nawfal

6
ฉันต้องการกาแฟหนึ่งถ้วยจากสตาร์บัคส์ที่ร้านเปิดจนถึงเที่ยงคืน ฟังดูคุ้นหูหรือเปล่า? มันอยู่ในลำดับเดียวกันกับแบบสอบถาม SQL ใช่ LINQ อาจอ่านได้มากกว่ารหัสที่ไม่จำเป็นที่คุณต้องสร้างเพื่อดำเนินการสืบค้น SQL มาตรฐาน แต่ LINQ ไม่สามารถอ่านได้มากกว่าแบบสอบถาม SQL เอง ใช่; มันอาจเป็นประโยชน์สำหรับนักพัฒนา LINQ ในการกำหนดขอบเขตจากซ้ายไปขวา แต่ในฐานะผู้ใช้ฉันจะสนใจอย่างไร ฉันสนใจแค่การใช้งานเท่านั้น
KyleM

8
@ KyleM: แน่นอน; การใช้งานเป็นสิ่งสำคัญมากในการออกแบบ LINQ โดยเฉพาะอย่างยิ่งการตอบสนองต่อเครื่องมือเพิ่มประสิทธิภาพเป็นกุญแจสำคัญ เนื่องจากการกำหนดขอบเขตไหลจากซ้ายไปเขียนในเคียวรี LINQ ตามเวลาที่คุณพิมพ์c.IDE รู้ประเภทcและสามารถให้ IntelliSense แก่คุณได้ ใน LINQ คุณพูดว่า "จาก c ในลูกค้าที่ c" และความเจริญคุณจะได้รับ IntelliSense Customerช่วยให้คุณโดยรายชื่อสมาชิกของ ใน SQL เมื่อคุณพิมพ์ "SELECT ชื่อจากลูกค้า" คุณไม่ได้รับความช่วยเหลือใด ๆ IDE จะบอกคุณว่า "ชื่อ" เป็นทางเลือกที่ดีเพราะคุณพิมพ์ก่อนname customers
Eric Lippert

22

เช่นเดียวกับสิ่งอื่นใดในโลกแห่งการเขียนโปรแกรมคุณต้องคุ้นเคยกับไวยากรณ์แล้วอ่านง่ายขึ้น (อาจ)

เช่นเดียวกับสิ่งอื่น ๆ ในโลกแห่งการเขียนโปรแกรมมีความเป็นไปได้สำหรับสปาเก็ตตี้โค้ดหรือการใช้ในทางที่ผิดอื่น ๆ

เช่นเดียวกับสิ่งอื่นใดในโลกแห่งการเขียนโปรแกรมคุณสามารถทำได้ด้วยวิธีนี้หรืออีกวิธีหนึ่ง

เช่นเดียวกับสิ่งอื่นใดในโลกแห่งการเขียนโปรแกรมไมล์สะสมของคุณอาจแตกต่างกันไป


6

ฉันเห็นความคิดเห็น / ข้อสังเกตซึ่งระบุบางสิ่งบางอย่าง - ที่เกี่ยวข้องกับ LINQ / แลมบ์ดา - ตามแนวของ: "เขียนโค้ดที่อ่านได้สำหรับมนุษย์แทนที่จะอ่านบนคอมพิวเตอร์ของคุณ"

ฉันคิดว่าคำแถลงนี้มีข้อดีมากมาย แต่ให้พิจารณาผู้พัฒนา (เช่นตัวฉันเอง) ที่ผ่านช่วงการพัฒนาภาษาจาก Assembly ผ่านขั้นตอนผ่าน OO ผ่านการจัดการผ่านการจัดการภาระงานสูง .

ฉันภูมิใจในการสร้างรหัสของฉันให้อ่านได้และนำมาใช้ซ้ำได้มากที่สุดและใช้หลักการรูปแบบการออกแบบ GOF จำนวนมากเพื่อส่งมอบระบบและบริการคุณภาพการผลิตในภาคธุรกิจที่แตกต่างกันจำนวนมาก

ครั้งแรกที่ฉันพบแลมบ์ดานิพจน์ฉันคิดว่า: "นั่นมันอะไรกันเนี่ย!?!" มันเป็นไวยากรณ์ที่ชัดเจนที่คุ้นเคย (และสะดวกสบาย) ของฉันในการตอบโต้ทันที อายุน้อยกว่า 5 ปีในกลุ่มงานแต่กระหน่ำมันเหมือนมานาจากสวรรค์!

นั่นเป็นเพราะหลายปีที่คิดเช่นเดียวกับคอมพิวเตอร์ (ในแง่ของคำศัพท์) แปลได้ง่ายมากในรูปแบบการเข้ารหัสโดยตรง (โดยไม่คำนึงถึงภาษา) เมื่อคุณมีความคิดว่าการคำนวณสำหรับประมาณ 20 ปี + (30 + ในกรณีของฉัน) คุณต้องชื่นชมว่าประโยคเริ่มต้นช็อตของการแสดงออกแลมบ์ดาสามารถแปลเป็นความกลัวและความไม่ไว้วางใจ

บางทีเพื่อนร่วมงานใน OP อาจมาจากภูมิหลังที่คล้ายกันกับตัวเอง (เช่นอยู่รอบบล็อกสองสามครั้ง) และมันก็ตอบโต้พวกเขาได้ง่ายในเวลานั้น? คำถามของฉันคือคุณทำอะไรกับมัน คุณพยายามให้ความรู้แก่เพื่อนของคุณอีกครั้งเพื่อทำความเข้าใจเกี่ยวกับประโยชน์ของไวยากรณ์แบบอินไลน์หรือคุณประจาน / เนรเทศพวกเขาโดยไม่ "อยู่กับโปรแกรม" หรือไม่? อดีตอาจจะเห็นเพื่อนร่วมงานของคุณมาถึงแนวความคิดของคุณหลังอาจทำให้พวกเขาไม่ไว้วางใจไวยากรณ์ LINQ / แลมบ์ดามากยิ่งขึ้นและทำให้ความคิดเห็นเชิงลบเลวร้ายยิ่งขึ้น

สำหรับตัวฉันเองฉันต้องรู้วิธีคิดของตัวเองอีกครั้ง (อย่างที่เอริค infers ข้างต้นมันไม่เปลี่ยนความคิดที่ไม่มีนัยสำคัญและฉันต้องเขียนโปรแกรมในมิแรนดาในยุค 80 ดังนั้นฉันจึงมีส่วนร่วมในการเขียนโปรแกรม แต่เมื่อฉันได้รับความเจ็บปวดนั้นประโยชน์ก็ชัดเจน แต่ที่สำคัญกว่านั้นคือการใช้งานอย่างแพร่หลาย (เช่นใช้เพื่อประโยชน์ในการใช้) มากกว่าที่ซับซ้อนและซ้ำซ้อน (พิจารณาหลักการ DRY ในตัวอย่างนั้น)

ในฐานะที่เป็นคนที่ไม่เพียง แต่ยังคงเขียนรหัสจำนวนมาก แต่ยังมีการตรวจสอบทางเทคนิคของรหัสจำนวนมากมันเป็นสิ่งจำเป็นที่ฉันเข้าใจหลักการเหล่านี้เพื่อให้ฉันสามารถตรวจสอบรายการที่เป็นกลางแนะนำการใช้แลมบ์ดาแสดงออก สามารถอ่านได้และเพื่อให้ผู้พัฒนาพิจารณาถึงความสามารถในการอ่านนิพจน์แลมบ์ดาแบบอินไลน์ที่ซับซ้อนสูง (ซึ่งการเรียกเมธอดจะ - ในกรณีเหล่านี้ - ทำให้โค้ดอ่านได้ง่ายขึ้นสามารถบำรุงรักษาได้และขยายได้)

ดังนั้นเมื่อมีคนบอกว่าพวกเขา "ไม่ได้แลมบ์ดา" หรือไวยากรณ์ LINQ แทนที่จะเป็นแบรนด์ludditeพยายามช่วยให้พวกเขาเข้าใจหลักการพื้นฐาน พวกเขาอาจมีพื้นหลัง "โรงเรียนเก่า" เช่นตัวเอง


ความคิดเห็นที่น่าสนใจ - ฉันมีสิ่งนี้เมื่อฉันเปลี่ยนจากภาษาที่คงที่ที่พิมพ์อย่างรุนแรงเป็นภาษาไดนามิก เอาฉันไปสักพักเพื่อปรับ (ความกลัวและความไม่ไว้วางใจ) และตอนนี้ฉันพบว่ามันยากที่จะกลับไปโดยสุจริต
lunchmeat317

4

แลมบ์ดานิพจน์ทำให้รหัสที่อ่านได้น้อยลงหากข้อความค้นหายาวเกินไป แต่มันจะดีกว่ามากเกินไปลูปซ้อนกัน

จะดีกว่าที่มีส่วนผสมของทั้งสอง

เขียนในแลมบ์ดาถ้ามันเร็วกว่า (คุณต้องใช้ให้เร็ว) หรืออ่านง่ายขึ้น


ใช่ แต่สิ่งที่จะทำให้อ่าน linq / lamda ไม่ง่ายขึ้น?
BlackICE

ขอโทษหมายถึงอ่านง่ายกว่าทางเลือกอื่น
BlackICE

1

ฉันคิดว่ามันขึ้นอยู่กับกรณีส่วนใหญ่ (ยกเว้นเมื่อทำสิ่งที่แปลกประหลาดมาก) ถ้าคุณหมายถึง "อ่าน" เป็นคนที่ได้รับความคิดของสิ่งที่เกิดขึ้นหรือถ้าพวกเขาสามารถหารายละเอียดเล็ก ๆ น้อย ๆ ได้อย่างง่ายดาย

ฉันคิดว่าลิงก์ช่วยในอดีต แต่บ่อยครั้ง (โดยเฉพาะเมื่อแก้ไขข้อบกพร่อง) เจ็บหลัง

IMHO เมื่อฉันดูรหัสฉันไม่คุ้นเคยกับอดีตมีความสำคัญมากกว่าสมัยก่อนดังนั้นฉันจึงพบว่าอ่านง่ายกว่ามาก


จุดดี. หลังมักจะครอบคลุมโดยการทดสอบหน่วยที่ดี
Scott Whitlock

ดังนั้นคุณคิดว่าการประเมินผลภายใน linq ทำให้ยากที่จะหารายละเอียดทั้งหมดหรือไม่ คุณสามารถให้ตัวอย่างของสิ่งที่อาจเป็นเมื่อ
BlackICE

3
@ David: สำนวน Linq ไม่เพียง แต่ขี้เกียจประเมินพวกเขากำลังแสดงออก โค้ดที่รับของนิพจน์ linq สามารถแก้ไขนิพจน์ได้ดังนั้นจึงทำสิ่งที่แตกต่างอย่างสิ้นเชิงเช่นแมโคร lisp ที่ทำงานกับ s-expressions ตัวอย่างเช่นเมื่อทำงานกับ linq เป็น SQL จะใช้การแสดงออกwhere e.FirstName == "John"และแปลว่าเป็นแบบสอบถาม SQL! มันทำได้โดยดูที่นิพจน์ที่ยังไม่ได้คอมไพล์ (แต่แยกวิเคราะห์) การเห็นว่าเป็นการเปรียบเทียบคุณสมบัติที่เรียกว่าFirstNameเอนทิตีที่ยังคงอยู่และเปรียบเทียบกับสตริงและอื่น ๆ
Scott Whitlock

@ David ทั่วไปฉันไม่พบรายละเอียดยากที่จะหาจนกว่าคุณจะเริ่มใช้ linq กับตัวเอง ตัวอย่าง "ง่าย ๆ " ของสิ่งนี้ที่ใช้เวลานานกว่าจะตัดหัวของฉันคือ: bugsquash.blogspot.com/2008/07/y-combinator-and-linq.htmlแต่มีบางอย่างที่จำเป็นมากกว่าในบางตัวอย่าง ในสิ่งที่ผู้คนกำลังทำด้วยนิพจน์ในพื้นที่ DynamicObject และ IDynamicMetaObjectProvider แบบไดนามิก โดยที่คุณวาดเส้นว่าอะไรคือ linq ที่สามารถถกเถียงกันได้ แต่เนื่องจากสกอตชี้ให้เห็นว่าทุกสิ่งนั้นมีอยู่ใน / ใน linq เพราะ linq ใช้ต้นไม้นิพจน์เดียวกัน
Bill

@ แต่เอาล่ะฉันจะให้มันยาก แต่ y-combinator และฟังก์ชั่นการสั่งซื้อสูงจะทำให้หัวของพวกเราส่วนใหญ่เจ็บเหมือนการเรียกซ้ำคุณไม่ได้หรือไม่ การใช้งานแบบวนซ้ำของการอ่านนั้นง่ายขึ้นหรือไม่ (หากคุณไม่รู้จัก)
BlackICE

1

ฉันพบว่าไวยากรณ์ LINQ ใช้งานง่ายและอ่านง่ายโดยเฉพาะอย่างยิ่งเนื่องจากวาง FROM ตั้งแต่เริ่มต้นซึ่งเป็นเจ้าของแทนที่จะอยู่ตรงกลางเหมือนใน SQL แต่ลูกแกะของ IMO นั้นสับสนและทำให้อ่านรหัสยากขึ้น


ทำไมคุณคิดว่าลูกแกะกำลังสับสน? มันเป็นข้อสรุปประเภท?
ChaosPandion

1
@ChaosPandion: ก่อนอื่นให้อนุมานประเภทและอย่างที่สองคือสัญลักษณ์ การใส่ = และ a เข้าด้วยกันดูเหมือนว่า> = ที่ใครบางคนเมาและเขียนไปข้างหลังและมันก็มีแนวโน้มที่จะขว้างสมองของฉันเป็นวง
Mason Wheeler

@Mason - คุณชอบไวยากรณ์ของ Haskell ( \x -> x * x) หรือ F # ( fun x -> x * x) หรือไม่
ChaosPandion

@ChaosPandion: ไม่ไม่เฉพาะ แลมบ์ดาอาจจะเขียนได้อย่างรวดเร็ว แต่ฉันพบว่ามันยากที่จะแยกวิเคราะห์โดยเฉพาะอย่างยิ่งเมื่อพวกเขากลายเป็นเรื่องซับซ้อน ตัวอย่างของคุณไม่ได้แย่ขนาดนั้น แต่พวกเขาก็มีแนวโน้มที่จะแย่ลงมาก
Mason Wheeler

6
@ ช่างก่ออิฐ: ดูเหมือนว่าคุณกำลังคัดค้านการถูกทำร้ายโดยลำพองมากกว่าที่จะคัดค้านความคิดของแลมดาในตอนแรก
อานนท์

1

ฉันเห็นด้วยกับคุณว่าไวยากรณ์ Linq ไม่แตกต่างจาก T-SQL อย่างมีนัยสำคัญ ฉันคิดว่าเพื่อนร่วมงานของคุณอาจจะไม่พอใจกับสิ่งที่สัมพันธ์กันมากขึ้นซึ่งรหัส OO ที่ดีและเป็นประกายของเขา ในทางกลับกันการเขียนโปรแกรมที่ใช้งานได้ใช้เวลาเล็กน้อยในการทำความคุ้นเคยและความเต็มใจที่จะทำความคุ้นเคย


0

มันขึ้นอยู่กับ. เห็นได้ชัดว่า T-SQL มีโซลูชัน DB-relational บางส่วนที่ไม่ซ้ำกัน เห็นได้ชัดว่า LINQ มอบโซลูชั่น OO บางอย่างโดยเฉพาะ

อย่างไรก็ตาม; "สับสนมากกว่า T-SQL เหรอ?" - ถูกกล่าวถึง / ถามในคำถามเริ่มต้น นี่แสดงให้เห็นอย่างชัดเจนถึงฟีเจอร์บางอย่างที่ไม่มีคำตอบที่มีอยู่แทนที่จะกล่าวหานักวิจารณ์ (ที่รู้จักกันอย่างชัดเจนใน SQL) แทนที่จะติดอยู่ในอดีต

ดังนั้นแม้ว่าฉันจะขอขอบคุณ LINQ สำหรับคุณสมบัติบางอย่างและไม่เห็นด้วยอย่างยิ่งกับคำตอบที่มีอยู่ที่นี่ แต่ฉันรู้สึกว่าจุดคู่ควรที่จะเป็นตัวแทน:

หลายปีหลังจากคุ้นเคยกับ LINQ การปฏิบัติงานกลุ่มบางอย่างการรวมภายนอกและไม่ equijoins การทำงานกับคีย์ผสมและการดำเนินการอื่น ๆ ใน LINQ ยังทำให้ฉันรู้สึกอึดอัด (โดยเฉพาะเมื่อกำหนดเป้าหมายส่วนหลังเชิงสัมพันธ์ด้วยคำถามที่มีความอ่อนไหวด้านประสิทธิภาพ)

from c in categories
join p in products on c equals p.Category into ps
from p in ps.DefaultIfEmpty()

หากคุณคิดว่ามันใช้งานง่ายพลังมากขึ้นสำหรับคุณ ;)


-4

อาจมีเหตุผลว่าทำไม Linq แย่แค่ลองทำตัวอย่างในโลกแห่งความเป็นจริงแทนที่จะเป็นตัวอย่างตำราเรียนเหล่านี้

พยายามที่จะแสดงฟังก์ชั่นนี้ใน linqlamdathings และคุณจะเห็นว่าความงามทั้งหมดหายไปในขณะที่วิธีคลาสสิกยังคงสามารถอ่านได้ ไม่ต้องพูดถึงปัญหาการดำเนินการรอการตัดบัญชีและการตั้งค่าจุดพัก

ความจริงก็คือ LinqLambda สิ่งที่มีประโยชน์มากในบางกรณีและพวกเขาไม่คิดว่าจะมาแทนที่การวางแนววัตถุที่ดีที่พวกคุณไม่เคยเข้าใจ

    public IList<Customer> GetVipCustomers(IList<Customer> source, int maxCount)
    {
        var results = new SortedList<string,Customer>();

        foreach (Customer c in source)
        {
            if (maxCount == results.Count)
                break;

            if (c.IsVip && c.FirstName== "Aaron" || c.SecondName== "Aaron")
                results.Add(c.LastName, c);
        }

        return results.Values;
    }

6
ฉันคิดว่ามันsource.Where(c => c.IsVip && c.FirstName == "Aaron" || c.SecondName == "Aaron").Take(maxCount).OrderBy(d => d.LastName);เป็นการยากที่จะอ่านของคุณดังนั้นฉันอาจทำผิด;)
jk

1
คุณคิดว่าสิ่งเหล่านี้เป็นตัวอย่างในตำราเรียนในทางใดบ้าง นั่นคือรหัสการใช้งานจริง มันจะช่วยถ้าคุณให้ทั้งรหัส "อ่าน" คลาสสิกของคุณและรุ่น linq / lamda สำหรับการเปรียบเทียบแทนการคาดหวังให้ทุกคนแปลง
BlackICE

3
คุณลงทะเบียนโดยเฉพาะเพื่อบ่นเกี่ยวกับ LINQ หรือไม่?
KChaloux

1
@Kalha ฉันคิดว่าพวกเขาแค่หลอกให้ซื่อสัตย์
jk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.