ใน. 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.
เหตุใดคุณจึงคาดหวังให้อาร์เรย์เรียกใช้ตัวสร้างที่แตกต่างกันไปยังรายการสำหรับโครงสร้าง