c# - Generate const strings at compile time for switch cases -
we have in legacy code base on .net 4.5 (important) static class defines many const string values of object types (means values of x.gettype().tostring()
) usage in switch statements.
this bad because refactorings break switch statements , places used vast can't change it. know other solutions if write now, but:
is there way - without changes switch statements - define const strings of types pickup compile time type since have information need @ compile time.
i know switch statements compiled @ compile time lookup table , not evaluate expression in cases, there way define const value once @ compile time? thing can think of dynamically generate code before build. there other solution?
c# 6 introducing feature solve exact problem, the nameof
expression.
using system; public class program { public static void main() { test(new foo()); test(new bar()); } private static void test(object x) { switch(x.gettype().tostring()) { case nameof(foo): console.writeline("inside foo's code"); break; case nameof(bar): console.writeline("inside bar's code"); break; } } } public class foo {} public class bar {}
the foo
, bar
referenced in nameof
types, if rename class automatic refactoring tools replace type in nameof
.
edit: did not catch "do not modify switch" part, can use constant strings too.
const string fooname = nameof(foo); const string barname = nameof(bar); private static void test(object x) { switch(x.gettype().tostring()) { case fooname: console.writeline("inside foo's code"); break; case barname: console.writeline("inside bar's code"); break; } }
update: nameof
not return full name namespace type name, type.tostring()
include namespace. maybe not work.
if can't use c# 6 option use t4 text templates dynamically build constants switch statements. issue assembly holds types referencing can not exist in same assembly generating code in.
the following code assumes have project named datatrasferobjects in same solution classes named foo
, bar
<#@ template debug="false" hostspecific="false" language="c#" #> <#@ assembly name="system.core" #> <#@ assembly name="$(solutiondir)\datatrasferobjects\bin\debug\datatrasferobjects.dll" #> <#@ import namespace="system" #> <#@ output extension=".cs" #> <# type footype = typeof(datatrasferobjects.foo); type bartype = typeof(datatrasferobjects.bar); #> public static class names { public const string fooname = "<#= footype.tostring() #>"; public const string barname = "<#= bartype.tostring() #>"; }
note, need configure build server automatically regenerate code on each build.
Comments
Post a Comment