消除预处理器命令的方法

时间:2010-08-31 20:39:01

标签: c#

我需要一种方法来显示这个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()

这会有用吗?我该怎么写这个班?

4 个答案:

答案 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版本。