[{"data":1,"prerenderedAt":117},["ShallowReactive",2],{"/2025/11/12-enum-constants-and-somewhere-in-between":3},{"id":4,"title":5,"body":6,"date":108,"description":38,"extension":109,"meta":110,"navigation":111,"path":112,"robots":113,"seo":114,"stem":115,"__hash__":116},"posts/2025/11/12 enum-constants-and-somewhere-in-between.md","12 Enum Constants And Somewhere In Between",{"type":7,"value":8,"toc":105},"minimark",[9,18,21,25,39,41,53,61,64,72,75,83,86,94,97],[10,11,13],"post-title",{":date":12},"date",[14,15,17],"h1",{"id":16},"enum-constants-and-somewhere-in-between","Enum, Constants, and Somewhere in Between",[19,20],"br",{},[22,23,24],"p",{},"I was showing a younger developer in my team on some techniques to implement strongly typed constants without using enum. For example, we have a method/function:",[26,27,28],"code-block",{},[29,30,35],"pre",{"className":31,"code":33,"language":34},[32],"language-text","public async void DoSomething(string activity)\n","text",[36,37,33],"code",{"__ignoreMap":38},"",[19,40],{},[22,42,43,44,48,49,52],{},"And we want to limit the value of activity parameter to let say ",[45,46,47],"strong",{},"Run"," and ",[45,50,51],{},"Bike",". One way is to use enum:",[26,54,55],{},[29,56,59],{"className":57,"code":58,"language":34},[32],"public enum Activity\n{\n    Run,\n    Bike\n}\n\npublic async void DoSomething(Activity activity)\n\npublic async void DoToday()\n{\n    DoSomething(Activity.Run);\n}\n",[36,60,58],{"__ignoreMap":38},[22,62,63],{},"Sometimes, we want to get the string value and enum can be tricky, so there's a tendency to loosen the parameter type, let say using static property or string constants.",[26,65,66],{},[29,67,70],{"className":68,"code":69,"language":34},[32],"public class Activity\n{\n    public static string Run { get; set; } = \"Run\";\n    public static string Bike { get; set; } = \"Bike\";\n}\n\npublic async void DoSomething(string activity)\n{\n  Debug.WriteLine($\"Activity: {activity}\")\n}\n\npublic async void DoToday()\n{\n    DoSomething(Activity.Run);\n}\n",[36,71,69],{"__ignoreMap":38},[22,73,74],{},"Which means the following is now valid but not intended:",[26,76,77],{},[29,78,81],{"className":79,"code":80,"language":34},[32],"DoSomething(\"Sleep\");\n",[36,82,80],{"__ignoreMap":38},[22,84,85],{},"So, how do we find a sweet spot between enum and string? One option is to use class but lock down the constructor so it can't be initialized with unintended value. This way, it is still flexible enough to extract the string value.",[26,87,88],{},[29,89,92],{"className":90,"code":91,"language":34},[32],"public class Activity\n{\n    private readonly string _value;\n    private Activity(string value) { _value = value; }\n    public static Activity Run { get; set; } = new Activity(\"Run\");\n    public static Activity Bike { get; set; } = new Activity(\"Bike\");\n    public string Value { get { return _value; } }\n}\n\npublic async void DoSomething(Activity activity)\n{\n    Debug.WriteLine($\"Activity: {activity.Value}\");\n}\n\npublic async void DoToday()\n{\n    DoSomething(Activity.Run);\n}\n",[36,93,91],{"__ignoreMap":38},[22,95,96],{},"The compiler will flag the following as invalid, thus we can control what are valid values for the activity parameter.",[26,98,99],{},[29,100,103],{"className":101,"code":102,"language":34},[32],"DoSomething(new Activity(\"Sleep\"));\n",[36,104,102],{"__ignoreMap":38},{"title":38,"searchDepth":106,"depth":106,"links":107},2,[],"2025-11-12T00:00:00.000Z","md",{},true,"/2025/11/12-enum-constants-and-somewhere-in-between",null,{"title":5,"description":38},"2025/11/12 enum-constants-and-somewhere-in-between","Bf1PI2GQA0InGywlsNrYA-06oSmXUs2YBU7CYJKMdUI",1785167452565]