C# 6 引入了一个特性来解决这个问题,nameof
表达式.
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 {}
运行示例
nameof
中引用的 Foo
和 Bar
是类型,如果您重命名类,则任何自动重构工具也会替换 nameof
中的类型。
编辑:没有注意到“不修改开关”部分,您也可以将其与常量字符串一起使用。
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;
}
}
更新:
nameof
方法只返回类型名称而不包括命名空间,而
Type.ToString()
则包括命名空间。因此,可能无法使用该方法。
如果您无法使用 C# 6,则可以使用
T4 文本模板为 switch 语句动态构建常量。但是,唯一的问题是持有所引用类型的程序集不能存在于您正在生成代码的同一个程序集中。
以下代码假定您在同一个解决方案中有一个名为 DataTrasferObjects 的项目,其中包含名为
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() #>";
}
请注意,在每次构建时您需要
配置您的构建服务器以自动重新生成代码。