C#6被引入特征来解决这个确切的问题,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 {}
Run Example
的Foo
和Bar
在nameof
引用的类型,如果重命名类中的任何自动重构工具也将取代类型的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;
}
}
UPDATE:nameof
不与命名空间只是类型名称,其中Type.ToString()
不包括命名空间返回全名。所以也许这不起作用。
如果您不能使用C#6的另一个选择是使用T4 Text templates来动态建立常量的开关语句。与此唯一的问题是组件,它拥有您引用的类型不能存在于您生成的代码所在的相同程序集中。
以下代码假定您有一个名为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() #>";
}
注意,您将需要configure your build server自动重新生成每个生成的代码。
我应该补充说,我卡在.NET 4.5,现在,需要该版本的解决方案。但除了代码生成之外,我没有看到任何其他内容,这是不必要的复杂。我没有看到任何简单的解决方案。 – Sam
是的,我想不出任何适用于C#5或更低版本的非代码生成解决方案(仅供参考,您可以将C#6与.NET 4.5一起使用,您只需通过搭建到发布的版本来更改编译器与VS2015)编辑:如果我得到时间,没有人有回应,我可能会尝试写出另一个答案,显示如何用T4代码genration做到这一点。 –
我添加了一个.net版本,如果你有一个T4的例子,对于这个问题是有好处的 – Sam