ฉันกำลังเขียนรหัสนี้:
private static Expression<Func<Binding, bool>> ToExpression(BindingCriterion criterion)
{
switch (criterion.ChangeAction)
{
case BindingType.Inherited:
var action = (byte)ChangeAction.Inherit;
return (x => x.Action == action);
case BindingType.ExplicitValue:
var action = (byte)ChangeAction.SetValue;
return (x => x.Action == action);
default:
// TODO: Localize errors
throw new InvalidOperationException("Invalid criterion.");
}
}
และรู้สึกประหลาดใจที่พบข้อผิดพลาดในการคอมไพล์:
ตัวแปรท้องถิ่นชื่อ 'การกระทำ' ถูกกำหนดไว้แล้วในขอบเขตนี้
มันเป็นปัญหาที่แก้ไขได้ง่าย เพียงแค่กำจัดวินาทีที่var
ไม่ได้หลอกลวง
ตัวแปรที่ประกาศชัดเจนในcase
บล็อกมีขอบเขตของผู้ปกครองswitch
แต่ฉันอยากรู้ว่าทำไมถึงเป็นเช่นนี้ ระบุว่า C # ไม่อนุญาตให้มีการดำเนินการที่จะตกผ่านกรณีอื่น ๆ (มันต้อง break
, return
, throw
หรือgoto case
งบในตอนท้ายของทุกcase
บล็อก) มันดูเหมือนว่าค่อนข้างแปลกที่มันจะช่วยให้การประกาศตัวแปรภายในหนึ่งcase
ที่จะใช้หรือขัดแย้งกับตัวแปรในอื่น ๆcase
. ในคำอื่น ๆ ตัวแปรปรากฏอยู่ในcase
งบแม้ว่าการดำเนินการไม่สามารถ C # ใช้ความเจ็บปวดอย่างมากในการส่งเสริมการอ่านโดยการห้ามไม่ให้มีการสร้างภาษาอื่นที่สับสนหรือถูกทารุณกรรมได้ง่าย แต่ดูเหมือนว่ามันแค่ก่อให้เกิดความสับสน พิจารณาสถานการณ์สมมติต่อไปนี้:
หากจะเปลี่ยนเป็น:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: return (x => x.Action == action);
ฉันได้รับ "การใช้งานตัวแปรท้องถิ่นที่ไม่ได้กำหนด 'การกระทำ' " นี่คือความสับสนเพราะในการสร้างอื่น ๆ ใน C # ที่ฉันสามารถคิดว่า
var action = ...
จะเริ่มต้นตัวแปร แต่ที่นี่มันก็ประกาศถ้าฉันจะสลับกรณีเช่นนี้:
case BindingType.ExplicitValue: action = (byte)ChangeAction.SetValue; return (x => x.Action == action); case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action);
ฉันได้รับ " ไม่สามารถใช้ 'การกระทำ' ตัวแปรท้องถิ่นก่อนที่จะมีการประกาศ " ดังนั้นลำดับของบล็อกเคสจึงมีความสำคัญที่นี่ในแบบที่ไม่ชัดเจน - โดยปกติฉันสามารถเขียนสิ่งเหล่านี้ในลำดับใดก็ได้ที่ฉันต้องการ แต่เนื่องจาก
var
ต้องปรากฏในบล็อกแรกที่action
ใช้ฉันจึงต้องปรับแต่งcase
บล็อก ตามหากจะเปลี่ยนเป็น:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: action = (byte)ChangeAction.SetValue; goto case BindingType.Inherited;
จากนั้นฉันก็จะไม่เกิดข้อผิดพลาด แต่อย่างใดดูเหมือนว่าตัวแปรจะถูกกำหนดค่าก่อนที่จะมีการประกาศ
(แม้ว่าฉันจะไม่สามารถนึกถึงเวลาที่คุณต้องการทำสิ่งนี้จริง ๆ - ฉันไม่เคยรู้goto case
มาก่อนว่าวันนี้)
ดังนั้นคำถามของฉันคือทำไมนักออกแบบของ C # ไม่case
บล็อกขอบเขตของตนเอง มีเหตุผลทางประวัติศาสตร์หรือทางเทคนิคสำหรับสิ่งนี้หรือไม่?
switch
เลย - ฉันแค่อยากรู้เกี่ยวกับเหตุผลที่อยู่เบื้องหลังการออกแบบนี้
break
ไม่สามารถทำได้ใน C #
action
ตัวแปรของคุณก่อนswitch
คำสั่งหรือใส่แต่ละกรณีไว้ในเครื่องหมายวงเล็บของตัวเองและคุณจะได้รับพฤติกรรมที่เหมาะสม