ประกาศพจนานุกรมภายในคลาสคงที่


90

จะประกาศวัตถุพจนานุกรมแบบคงที่ภายในคลาสแบบคงที่ได้อย่างไร? ฉันเหนื่อย

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic = new Dictionary<string, string>()
    {
        { "1", "User name or password problem" }     
    };
}

แต่คอมไพเลอร์บ่นว่า " ฟิลด์ const ของประเภทการอ้างอิงอื่นที่ไม่ใช่สตริงสามารถเริ่มต้นด้วย nullเท่านั้น"


1
คุณไม่สามารถใช้ const กับประเภทพจนานุกรมได้เฉพาะกับค่าสเกลาร์ (ตรวจสอบคำตอบของฉัน) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona

คำตอบ:


215

หากคุณต้องการประกาศพจนานุกรมครั้งเดียวและไม่เคยเปลี่ยนแปลงให้ประกาศเป็นแบบอ่านอย่างเดียว:

private static readonly Dictionary<string, string> ErrorCodes
    = new Dictionary<string, string>
{
    { "1", "Error One" },
    { "2", "Error Two" }
};

หากคุณต้องการให้รายการพจนานุกรมเป็นแบบอ่านอย่างเดียว (ไม่ใช่แค่การอ้างอิง แต่รวมถึงรายการในคอลเลกชันด้วย) คุณจะต้องสร้างคลาสพจนานุกรมแบบอ่านอย่างเดียวที่ใช้ IDictionary

ตรวจสอบ ReadOnlyCollection สำหรับการอ้างอิง

BTW const สามารถใช้ได้เฉพาะเมื่อประกาศค่าสเกลาร์แบบอินไลน์


วิธีการมีระดับคลาสส่วนตัวคงที่ตัวแปรคงพจนานุกรมส่วนตัว <string, string> ErrorCodes จากนั้นในฟังก์ชันตามลำดับตรวจสอบว่า (ErrorCodes == null) {เติมพจนานุกรม} เป็นค่าแคชเมื่อใช้ในลูปหรือไม่
LifeOfPi

1
หากคุณไม่ต้องการให้เปลี่ยนพจนานุกรมคุณสามารถห่อเป็นไฟล์ReadOnlyDictionary. ตัวเลือกที่มีประสิทธิภาพมากขึ้น (แต่ปลอดภัยน้อยกว่า) คือการกำหนดให้เป็นIReadOnlyDictionaryประเภท
Ramon de Klein

8

ไวยากรณ์ที่ถูกต้อง (ตามที่ทดสอบใน VS 2008 SP1) คือ:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}

แต่สิ่งนี้ไม่ได้ป้องกันไม่ให้คลาสการบริโภคแก้ไขเนื้อหา
Everts

4

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

private static readonly StringDictionary SegmentSyntaxErrorCodes = new StringDictionary
{
    { "1", "Unrecognized segment ID" },
    { "2", "Unexpected segment" }
};

แก้ไข:ตามความคิดเห็นของ Chris ด้านล่างโดยทั่วไปแล้วการใช้Dictionary<string, string>over StringDictionaryเป็นที่ต้องการ แต่จะขึ้นอยู่กับสถานการณ์ของคุณ หากคุณกำลังจัดการกับฐานรหัสรุ่นเก่าคุณอาจถูก จำกัด ไว้ที่ไฟล์StringDictionary. นอกจากนี้โปรดทราบว่าบรรทัดต่อไปนี้:

myDict["foo"]

จะกลับ null ถ้าmyDictเป็นแต่มีข้อยกเว้นจะถูกโยนในกรณีของStringDictionary Dictionary<string, string>ดูโพสต์ SO ที่เขาพูดถึงสำหรับข้อมูลเพิ่มเติมซึ่งเป็นที่มาของการแก้ไขนี้



นั่นคือคำถามที่ฉันเชื่อมโยง
Chris Morgan

1
ฮาว้าวไม่ได้จับได้ - บังเอิญเจออันเดียวกัน ฉันไม่สามารถแก้ไขความคิดเห็นได้ดังนั้นฉันจึงแก้ไขโพสต์เพื่อสรุปในที่เดียว ขอบคุณ!
areyling

2

สร้างตัวสร้างแบบคงที่เพื่อเพิ่มค่าในพจนานุกรม

enum Commands
{
    StudentDetail
}
public static class Quires
{
    public static Dictionary<Commands, String> quire
        = new Dictionary<Commands, String>();
    static Quires()
    {
        quire.add(Commands.StudentDetail,@"SELECT * FROM student_b");
    }
}

1
สอบถามหรือสอบถาม?
เถ้า

1

ปัญหากับตัวอย่างเริ่มต้นของคุณสาเหตุหลักมาจากการใช้constมากกว่าstatic; คุณไม่สามารถสร้างการอ้างอิง const ที่ไม่ใช่ null ใน C #

ฉันเชื่อว่าสิ่งนี้จะได้ผลเช่นกัน:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic
        = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
}

นอกจากนี้ในขณะที่ Y Low ชี้ให้เห็นการเพิ่มreadonlyก็เป็นความคิดที่ดีเช่นกันและไม่มีตัวปรับแต่งใดที่กล่าวถึงในที่นี้จะป้องกันไม่ให้มีการแก้ไขพจนานุกรม


0

คุณสามารถใช้ตัวสร้างแบบคงที่ / คลาสเพื่อเริ่มต้นพจนานุกรมของคุณ:

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic;
    public static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}

1
คุณต้องการทำให้พจนานุกรมคงที่หรือไม่? คุณไม่สามารถมีได้ ตามที่ข้อความแสดงข้อผิดพลาดระบุเฉพาะประเภทค่าสตริงหรือ null เท่านั้นที่สามารถเป็น const
Orion Edwards

0

ทำให้พจนานุกรมเป็นแบบคงที่และอย่าเพิ่มเข้าไปนอก ctor ของวัตถุคงที่ของคุณ ดูเหมือนจะเป็นวิธีแก้ปัญหาที่ง่ายกว่าการเล่นซอกับกฎคงที่ / const ใน C #


0

ตกลง - ฉันทำงานใน ASP 2.x (ไม่ใช่ตัวเลือกของฉัน ... แต่เดี๋ยวก่อนใครเป็นคนเลว?)

ตัวอย่างพจนานุกรมเริ่มต้นใช้งานไม่ได้ จากนั้นฉันก็เจอสิ่งนี้: http://kozmic.pl/archive/2008/03/13/framework-tips-viii-initializing-dictionaries-and-collections.aspx

... ซึ่งทำให้ฉันทราบว่าไม่มีใครใช้การเริ่มต้นคอลเลคชันใน ASP 2.x.


-2
public static class ErrorCode
{
    public const IDictionary<string , string > m_ErrorCodeDic;

    public static ErrorCode()
    {
      m_ErrorCodeDic = new Dictionary<string, string>()
             { {"1","User name or password problem"} };             
    }
}

อาจเริ่มต้นในตัวสร้าง

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