ใน. NET ประเภทค่า (C # struct) ไม่สามารถมีตัวสร้างที่ไม่มีพารามิเตอร์ ตามโพสต์นี้ได้รับคำสั่งจากข้อกำหนดของ CLI สิ่งที่เกิดขึ้นคือสำหรับทุกประเภทค่าตัวสร้างเริ่มต้นจะถูกสร้างขึ้น (โดยคอมไพเลอร์?) ซึ่งเริ่มต้นสมาชิกทั้งหมดให้เป็นศูนย์ (หรือnull)
ทำไมมันไม่อนุญาตให้กำหนดคอนสตรัคเตอร์เริ่มต้นเช่นนี้
การใช้สิ่งเล็กน้อยสำหรับตัวเลขที่มีเหตุผล:
public struct Rational {
private long numerator;
private long denominator;
public Rational(long num, long denom)
{ /* Todo: Find GCD etc. */ }
public Rational(long num)
{
numerator = num;
denominator = 1;
}
public Rational() // This is not allowed
{
numerator = 0;
denominator = 1;
}
}
การใช้เวอร์ชันปัจจุบันของ C # ค่า Rational ที่เป็นค่าเริ่มต้น0/0จะไม่ดีนัก
PS : พารามิเตอร์เริ่มต้นจะช่วยแก้ปัญหานี้สำหรับ C # 4.0 หรือจะเรียกว่าตัวสร้างเริ่มต้นที่กำหนดโดย CLR
Jon Skeetตอบ:
หากต้องการใช้ตัวอย่างของคุณคุณต้องการทำอะไรเมื่อมีคนทำ:
Rational[] fractions = new Rational[1000];มันควรวิ่งผ่านตัวสร้างของคุณ 1,000 ครั้งหรือไม่
แน่นอนมันเป็นเหตุผลที่ฉันเขียนตัวสร้างเริ่มต้นตั้งแต่แรก CLR ควรใช้ตัวสร้างzeroing เริ่มต้นเมื่อไม่มีการกำหนดตัวสร้างเริ่มต้นที่ชัดเจน; ด้วยวิธีนี้คุณจ่ายเฉพาะสิ่งที่คุณใช้ ถ้าฉันต้องการตู้คอนเทนเนอร์ 1,000 กล่องไม่ใช่ค่าเริ่มต้นRational (และต้องการปรับการสร้าง 1,000 ครั้งให้เหมาะสม) ฉันจะใช้List<Rational>อาร์เรย์แทน
ในใจของฉันเหตุผลนี้ไม่แข็งแรงพอที่จะป้องกันคำจำกัดความของตัวสร้างเริ่มต้น
Rational()เรียก ctor parameterless Rational(long num=0, long denom=1)มากกว่า
new Rational()จะเรียก constructor ถ้ามันมีอยู่ แต่ถ้ามันไม่ได้อยู่ที่จะเทียบเท่ากับnew Rational() default(Rational)ในกรณีใด ๆ คุณควรใช้ไวยากรณ์default(Rational)เมื่อคุณต้องการ "ศูนย์ค่า" ของ struct ของคุณ (ซึ่งเป็นหมายเลข "ไม่ดี" กับการออกแบบที่เสนอของคุณRational) ค่าเริ่มต้นสำหรับประเภทค่าอยู่เสมอT default(T)ดังนั้นnew Rational[1000]จะไม่เรียกใช้ constructors construct
denominator - 1ไว้ใน struct เพื่อให้ค่าเริ่มต้นกลายเป็น 0/1
Then if I want a container of 1000 non-default Rationals (and want to optimize away the 1000 constructions) I will use a List<Rational> rather than an array.เหตุใดคุณจึงคาดหวังให้อาร์เรย์เรียกใช้ตัวสร้างที่แตกต่างกันไปยังรายการสำหรับโครงสร้าง