我需要一种方法来显示这个C#3.0代码:
[TestMethod]
#if NUNIT
[Moled]
#else
[HostType("Moles")]
#endif
public void TestSomething()
不使用/需要每种方法的预处理器命令。
这可能吗?
与同事交谈时,我们推测可能有一种方法可以创建一个具有2个构造函数的属性类(一个具有零参数,一个具有1个字符串)。然后在文件的顶部我们像这样做条件:
#if NUNIT
Moled = MyNamespace.MyNewAttribute;
#else
HostType = MyNamespace.MyNewAttribute;
#endif
MyNewAttribute类将被设置为什么都不做,所以我可以用这个编译:
[TestMethod]
[Moled]
[HostType("Moles")]
public void TestSomething()
这会有用吗?我该怎么写这个班?
答案 0 :(得分:2)
您更新的问题提供了一个有趣且(在我看来)可行的解决方案。
要完成它,您需要做的就是声明MyNewAttribute
,这应该很简单:
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class MyNewAttribute : Attribute
{
public MyNewAttribute() { }
public MyNewAttribute(string dummy) { }
}
在#if
技巧中,您必须使用完整的班级名称:
#if NUNIT
using MoledAttribute = MyNamespace.MyNewAttribute;
#else
using HostTypeAttribute = MyNamespace.MyNewAttribute;
#endif
注意:我不知道应该采用哪种方式 - 你的问题与此相矛盾。请记住,您需要重新定义要禁用的那个,而不是要启用的那个。
此外,在所有类型声明之前,这些using
语句必须首先在命名空间内。我试过这个,即使MyNewAttribute
在同一个文件中被进一步声明,它也能正常工作。
由于这是一个非常不寻常的技巧,我强烈建议对#if
构造进行解释性评论,以便未来的代码读者可以理解它的含义,为什么存在以及它是如何工作的。< / p>
顺便说一句,自定义属性名称只有这些,并且很少或没有构造函数参数,我个人觉得将它们放在一行中更具可读性:
[TestMethod, Moled, HostType("Moles")]
public void TestSomething()
答案 1 :(得分:2)
我不明白为什么你需要别名。只需在一个单个文件中执行此操作:
#if NUNIT
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class HostTypeAttribute : Attribute
{
public HostTypeAttribute(string dummy) { }
}
#else
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class MoledAttribute : Attribute
{
public MoledAttribute() { }
}
#endif
然后你可以在任何文件中使用这两个文件,除了这里之外没有任何预处理器定义。
答案 2 :(得分:0)
你接近正确的轨道。您只需要创建一个虚拟属性类,它可以取代您尝试切换的属性:
public sealed class DummyAttribute : Attribute
{
public DummyAttribute()
{}
pulic DummyAttribute(string dummy)
{}
}
这两个构造函数是必需的,因为您尝试替换的其中一个属性接受字符串作为参数。设置虚拟构造函数允许您忽略要替换的属性的实际行为。
然后,文件顶部的预处理程序块应如下所示:
#if !NUNIT
using Moled = MyNameSpace.DummyAttribute;
#else
using HostType = MyNameSpace.DummyAttribute;
#endif
答案 3 :(得分:-1)
当然,将其分成两个文件:
File1中:
[TestMethod]
[Moled]
public void TestSomething()
文件2:
[TestMethod]
[HostType("Moles")]
public void TestSomething()
使用适合的文件。
更新:
啊,我想我终于明白你所追求的是什么了
你没有真的希望“消除预处理程序指令”作为你原来的问题请求,你真正想要做的是根据预处理程序指令统一你的方法的属性。
是的,这可以通过using class alias的魔力来完成! 您将要感兴趣的两个属性类重命名为相同的名称,如下所示:
#if NUNIT
using MyAttrib = System.Diagnostics.ConditionalAttribute;
#else
using MyAttrib = System.ObsoleteAttribute;
#endif
然后你装饰所有你的方法:
[MyAttrib( "attrib arg" )]
public void TestSomething()
我自己做了同样的事情,因为当一个项目要通过Microsoft方式进行单元测试时,直到我们得到支持它的Visual Studio版本。