คุณลักษณะ C # หรือ. Net เพื่อตัดออกโดยไม่จำเป็นต้องใช้ความเข้ากันได้แบบย้อนหลังได้หรือไม่ [ปิด]


18

ผลิตภัณฑ์หรือกรอบงานใด ๆ วิวัฒนาการ โดยหลักแล้วมันจะทำเพื่อให้ทันกับความต้องการของผู้ใช้และใช้ประโยชน์จากพลังการประมวลผลใหม่และทำให้ดีขึ้น บางครั้งเป้าหมายการออกแบบหลักก็เปลี่ยนแปลงกับผลิตภัณฑ์ C # หรือ. net framework จะไม่มีข้อยกเว้น อย่างที่เราเห็นรุ่นปัจจุบันของรุ่นที่ 4 แตกต่างกันมากเมื่อเทียบกับรุ่นแรก แต่สิ่งที่มาเป็นสิ่งกีดขวางต่อความเข้ากันได้ของวิวัฒนาการนี้

ในส่วนใหญ่ของเฟรมเวิร์ก / ผลิตภัณฑ์มีคุณสมบัติที่จะถูกตัดออกหากไม่จำเป็นต้องรองรับความเข้ากันได้ย้อนหลัง คุณสมบัติเหล่านี้ใน C # /. net คืออะไร

กรุณาพูดถึงหนึ่งคุณสมบัติต่อคำตอบ



4
คำถามนี้ไม่ชัดเจนตามแนวทางและสร้างสรรค์อย่างชัดเจนตามคำตอบที่น่าอัศจรรย์ การโหวตเพื่อเปิดอีกครั้ง
psr

1
น่าเสียดายที่ปิดแล้วบางที Eric อาจบล็อกนี้แทนที่จะตอบที่นี่?
jk

คำตอบ:


35

วิธีการที่ไม่ระบุชื่อ ฉันคิดว่าทุกคนยอมรับว่าไวยากรณ์ของวิธีที่ไม่ระบุชื่อที่เลือกสำหรับ C # 2.0 นั้นเป็นก้อนและ clunky เมื่อเทียบกับไวยากรณ์ lambda ที่เราเพิ่มเข้าไปใน C # 3.0 โชคไม่ดีที่มีซินแท็กซ์สองตัวที่เกือบเหมือนกันในการทำสิ่งเดียวกัน


1
เห็นด้วยวิธีการไม่ระบุชื่อนั้นยอดเยี่ยมเมื่อเราไม่มีลูกแกะ ... ตอนนี้พวกมันซ้ำซ้อนกันแล้ว
Michael Brown

9
มีคุณสมบัติพิเศษอย่างหนึ่งของวิธีการไม่ระบุชื่อที่ดีกว่าการแสดงออกแลมบ์ดา .... ชื่อที่สมบูรณ์แบบของพวกเขา !!
สำรวจ

1
ณ จุดนี้ฉันไม่จำไวยากรณ์สำหรับวิธีที่ไม่ระบุชื่อใน C # ฉันต้องค้นหามันด้วยเหตุผลบางอย่างที่แปลกประหลาดฉันต้องใช้มันแทนแลมบ์ดา
Kyralessa

33

ฉันจะกำจัดคอลเล็กชันที่ไม่ใช่ทั่วไป พวกเขาเป็นสิ่งที่น่ารังเกียจ ... และมีหลายกรณีเกินไปที่ฉันใช้ linq และต้องทำอะไรบางอย่างเช่น

var customObjects = container.CustomObjects.Cast<CustomObject>();

ทุกครั้งที่ฉันต้องทำสิ่งนั้นส่วนเล็ก ๆ ในชีวิตของฉันก็ตาย


นี่มันยอดเยี่ยมเกินไป

1
ไม่ใช่ทุกพอร์ตของ. NET ที่สนับสนุน Generics .NET Micro เป็นตัวอย่าง อาจไม่สามารถใช้ได้ถ้า CustomObjects จะไม่ย้ายไปที่แพลตฟอร์มนี้
goodguys_activate

2
นั่นคือข้อดีที่จะไม่มีวิญญาณ
CaffGeek

29

เป็นโมฆะประเภท เหตุใดในโลกจึงเป็น "โมฆะ" ประเภท? ไม่มีอินสแตนซ์ไม่มีค่าคุณไม่สามารถใช้เป็นอาร์กิวเมนต์ชนิดทั่วไปชนิดพารามิเตอร์ที่เป็นทางการชนิดโลคัลชนิดฟิลด์หรือชนิดคุณสมบัติ มันไม่มีความหมายว่าเป็นประเภท; ค่อนข้างเป็นความจริงเกี่ยวกับผลกระทบที่การเรียกใช้เมธอดมีบนสแต็กของเครื่องเสมือน แต่เครื่องเสมือนนั้นเป็นเพียง: เครื่องเสมือน เครื่องจริงจะใส่ค่าที่ส่งคืนในรีจิสเตอร์ (โดยทั่วไปคือ EAX บน x86) และไม่มีผลกับสแต็กเลย! ความว่างเปล่าเป็นประเภทเป็นเพียงความคิดที่ไม่ดีรอบ ๆ

แย่ลง: เมื่อใช้ในประเภทตัวชี้ตามที่void*หมายถึงสิ่งที่แตกต่างอย่างสมบูรณ์กว่าสิ่งที่มันหมายถึงเมื่อใช้เป็นประเภทผลตอบแทน ตอนนี้มันหมายถึง "ตัวชี้ไปยังที่เก็บข้อมูลประเภทที่ไม่รู้จัก" ซึ่งไม่มีอะไรเกี่ยวข้องกับความหมายของมันในฐานะ "วิธีการที่ไม่คืนค่าใด ๆ "

เราสามารถเปลี่ยนเป็นชนิดชี้กับvoid* IntPtr(และvoid**ด้วยIntPtr*และต่อไปเรื่อย ๆ ) เราสามารถแทนที่โมฆะเป็นประเภทส่งคืนด้วย "หน่วย" ซึ่งเป็นประเภทที่มีค่าเดียวคือโมฆะ การนำไปใช้งานของ CLR สามารถตัดสินใจได้ว่าการเรียกใช้ฟังก์ชันที่พิมพ์หน่วยสามารถปรับการใช้งานของการลงทะเบียนหรือสแต็กอย่างเหมาะสมโดยรู้ว่า null ที่ถูก "ส่งคืน" สามารถละเว้นได้อย่างปลอดภัย

ในโลกใบนี้คุณไม่จำเป็นต้องแยกจากกันFunc<A, R>และเป็นAction<T>ตัวแทนอีกต่อไป เป็นเพียงAction<T>Func<T, Unit>


4
... และเป็นเพียงTask Task<Unit>Reimplementing บิตห้องสมุด async CTP ทำให้ฉันจริงๆต้องการนี้ ...
จอนสกีต

24

;คำสั่งที่ว่างเปล่า เกิดข้อผิดพลาดมักจะเป็นตัวพิมพ์ใหญ่และไม่ให้ความหมายใด ๆ ที่ยังไม่ได้แสดงออก{}มา


7
ไม่ต้องพูดถึงการลงโทษอย่างมากภายใต้ JIT 64 บิต </snark>
Jesse C. Slicer

7
คำแถลงที่ว่างเปล่ามีโทษประสิทธิภาพหรือไม่? ทำไมถึงเป็นอย่างนั้น?
quentin-starin

22

ความแปรปรวนไม่ปลอดภัยบนอาร์เรย์ของชนิดการอ้างอิง ด้วยความแปรปรวนร่วม typesafe IEnumerable<T>อย่างน้อยความจำเป็นในการแปรปรวนอาร์เรย์ได้หายไป (ถ้าเรามีอินเตอร์เฟซรายการอ่านอย่างเดียว covariant เราก็ไม่จำเป็นต้องใช้เลย)


ผมก็อย่างจะเขียนลงนี้เมื่อผมเห็นชื่อคำถาม - คุณชนะฉันไป :(
คริสสมิ ธ

1
ความสามารถในการรับการอ้างอิงอาร์เรย์ covariant และเขียนไปยังการอ้างอิงอาร์เรย์ที่อ่านได้อย่างปลอดภัยมีประโยชน์ ถ้าชอบIList<T>สืบทอดจากIReadableList<out T>และไม่ใช่ทั่วไปIPemutableก็สามารถรองรับสิ่งต่าง ๆ เช่นการเรียงลำดับ แต่อาร์เรย์สนับสนุนได้ง่ายขึ้น
supercat

14

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

(ชี้แจงผู้ประกอบการบวกเอก+xไม่ได้เป็นผู้ประกอบการ preincrement ++xไม่ประกอบ postincrement x++และไม่ดำเนินการนอกจากนี้ไบนารีx+y.)


1
สำหรับ (int i = 0; i <ceiling; i ++)
Michael Brown

13
เขาไม่ได้พูดคุยเกี่ยวกับ preincrement และ postincrement ผู้ประกอบการ: +1 == 1เขาพูดเกี่ยวกับเอกบวกตรงข้ามของเครื่องหมายลบกับจำนวนที่: มันค่อนข้างใกล้เคียงกับที่ไม่มี op
Jesse C. Slicer

8
if(a == +1 || a == -1){...}มันไม่ได้เป็นเพียงเกี่ยวกับผลกระทบต่อการส่งออกอ่านได้เครื่องก็สามารถปรับปรุงรูปลักษณ์ของสำหรับมนุษย์:
Thomas Bratt

5
@ShuggyCoUK: อะไรคือสิ่งที่แปลกประหลาดโดยเฉพาะอย่างยิ่งเกี่ยวกับเรื่องนี้ก็คือว่ามันเป็นoverloadable เพราะมันเกิดขึ้นมากมาย คุณจะรู้ว่าวิธีการที่คุณกำลังเขียนบาง JavaScript และคุณคิดว่าคนที่ฉันต้องการ JS อนุญาตให้ฉันเพื่อให้ผู้ใช้กำหนดเอกบวกประกอบความหมายเช่น C # ไม่
Eric Lippert

2
@Eric ฉันไม่ได้ตระหนักว่ามันเกินพิกัด ว้าวคุณสามารถทำบางอย่างที่น่ารังเกียจกับ obfuscation :) ว่า
ShuggyCoUk

12

การเริ่มต้นตัวอักษรตัวเลขเป็น double

สำหรับแอปทางธุรกิจส่วนใหญ่decimalมีความเหมาะสมมากกว่าอยู่แล้ว ... หรืออาจเป็นการดีกว่าที่จะลบแนวคิดของค่าเริ่มต้นออกและบังคับให้นักพัฒนาเลือกตัวเลือกจริง

(นั่น "ลบเริ่มต้น" จะเหมาะสมสำหรับสิ่งอื่น ๆ บางเกินไป. ตัวอย่างเช่นผมได้รับค่าพยายามที่จะชักชวนให้ทุกคนที่เรียนควรจะปิดผนึกโดยค่าเริ่มต้น แต่ฉันสงสัยว่ามันง่ายที่จะชักชวนให้คนที่พวกเขาควรจะคิดเกี่ยวกับ ควรจะปิดคลาสใหม่ของพวกเขาหรือไม่และทำให้ชัดเจน)


ฉันอาจจะยันการระบุตัวอักษรที่บ่งบอกถึงความคุ้มค่าที่ไม่สามารถแสดงเป็น / ลอยคู่อย่างแม่นยำ ...
ShuggyCoUk

หากพวกเขาเป็น Java - อ้างอิงพวกเขาไปยังข้อความศักดิ์สิทธิ์โดย Joshua Bloch "การออกแบบหรือเอกสารสำหรับการสืบทอดหรือมิฉะนั้นห้าม" martinfowler.com/bliki/DesignedInheritance.html IIRC kotlin ประทับตราคลาสโดยค่าเริ่มต้นดังนั้นอุตสาหกรรมจึงย้ายเข้ามา ทิศทางที่ดีขึ้นในส่วนนี้
Elazar Leibovich

ทำไมต้องปิดคลาส
James

@James: เหตุผลที่ Josh ให้ไว้ การออกแบบคลาสที่เปิดใช้งานการสืบทอดในแบบที่สมเหตุสมผลและสอดคล้องต้องใช้เวลา - โดยไม่ต้องรู้ว่าการใช้การสืบทอดนั้นจะยิ่งแย่ลงไปกว่านั้น
Jon Skeet

1
@Pacerier: ลองคิดถึงสิ่งที่ไม่สามารถเปลี่ยนแปลงได้เช่นกัน คลาสที่ไม่มีการปิดผนึกไม่สามารถอ้างสิทธิ์ว่าไม่เปลี่ยนรูปได้เนื่องจากคลาสย่อยสามารถแนะนำความไม่แน่นอนได้
Jon Skeet

7

นี่เป็นแนวทางมากกว่าฟีเจอร์ แต่ฉันคิดว่ามันสำคัญเพราะมันฝังลึกอยู่ในใจของผู้คนมากเกินไปในฐานะที่เป็นทางบัญญัติและเป็นทางออกที่ดีที่สุด:

รูปแบบอย่างเป็นทางการIDisposableในการดำเนินการ

มันยุ่งยากและมีกำลังวิธีที่ดีกว่า


6

ฉันรู้ว่ามีความแตกต่างใหญ่ระหว่างคลาสตัวจับเวลาต่าง ๆ แต่เราไม่สามารถกำจัดพวกเขาหนึ่งหรือสองคนได้หรือไม่?


4

วิธีการและประเภทของArrayและList<T>ที่ล้าสมัยกับ Linq ตัวอย่างเช่น:

  • Array.TrueForAll สามารถถูกแทนที่ด้วย Enumerable.All
  • Array.FindAll สามารถถูกแทนที่ด้วย Enumerable.Where
  • List<T>.ConvertAll สามารถถูกแทนที่ด้วย Enumerable.Select
  • Predicate<T> สามารถถูกแทนที่ด้วย Func<T, bool>
  • Converter<T,R> สามารถถูกแทนที่ด้วย Func<T, R>
  • IComparer<T> ควรเป็นตัวแทน Func<T, T, int>

3
ฉันชอบPredicate<T>เพราะมันจับความตั้งใจในการใช้งานฟังก์ชั่นและบันทึกการพิมพ์เล็กน้อย
Zebi

2

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


3
คุณจะกำหนดผู้รับมอบสิทธิ์ให้กับวิธีการที่ใช้การอ้างอิงด้วย Action หรือ Func อย่างไร คุณจะกำหนดcombinatorด้วย Func อย่างไร นั่นคือไม่มีวิธีพูดว่า "มอบหมาย DD (D d);" กับ Func
Eric Lippert

2
อืม ... ฉันยืนแก้ไขแล้ว นั่นเป็นเหตุผลที่ฉันออกจากงานของการสร้างเครื่องมือที่ฉันใช้ในมือที่มีความสามารถของคุณ;)
Michael Brown

@EricLippert: ฉันต้องการเห็นคลาสผู้ได้รับมอบหมายพิเศษซึ่งจะผ่าน CLR เวทมนต์ประกอบด้วยตัวแทนของ "ทุก ๆ " arity และการรวมกันของพารามิเตอร์ค่า / อ้างอิง [ค้นหาผู้แทนในคลาสเวทย์มนตร์ด้วยชื่อที่จัดรูปแบบเหมาะสม ประเภท] และมีผู้รับมอบสิทธิ์ทั้งหมดของลายเซ็นที่เหมาะสมสืบทอดมาจากนั้น รหัสที่ต้องการตัวแทนเฉพาะจะยังคงต้องการประเภทที่แน่นอน แต่รหัสที่ต้องการลายเซ็นเฉพาะสามารถใช้ชื่อเวทมนต์
supercat


-2

Winforms
เป็นเรื่องดีที่ไม่ต้องเลื่อนไปมาระหว่างสองแพลตฟอร์มเดสก์ท็อป WPF เป็นสิ่งที่เกิดขึ้นดังนั้นมันน่าผิดหวังที่มีความซ้ำซ้อนในระดับแพลตฟอร์ม


Winforms ดูเหมือนจะมีเสถียรภาพมากขึ้นเร็วขึ้นและมีความผิดพลาดน้อยกว่า WPF ...
Pacerier

เมื่อคุณต้องการแฮ็กแอปเดสก์ท็อปขนาดเล็กออก WPF ก็เป็น overkill ที่สำคัญ
Kyralessa

ดูเหมือนว่าในระหว่าง WPF กลายเป็นล้าสมัยในความโปรดปรานของ WinRT อย่างไรก็ตามสำหรับฉันดูเหมือนว่า Winforms นั้นมีชีวิตมากกว่า WPF ในการพัฒนาธุรกิจ ดูstackoverflow.com/questions/913417/…
Doc Brown
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.