接口(interface)成员的 C# 条件属性

标签 c# conditional-attribute

我试图通过使用 Conditional 属性来代替代码中的“#if TRACE”指令,但无法轻松地将此方法应用于接口(interface)。我有办法解决这个问题,但它很难看,我正在寻找更好的解决方案。

例如我有一个带有条件编译方法的接口(interface)。

interface IFoo
{
#if TRACE
    void DoIt();
#endif
}

我不能在接口(interface)中使用条件属性:

// Won't compile.
interface IFoo
{
    [Conditional("TRACE")]
    void DoIt();
}

我可以让接口(interface)方法只调用具体类中的条件私有(private)方法:

interface IFoo
{
    void TraceOnlyDoIt();
}

class Foo : IFoo
{
    public void TraceOnlyDoIt()
    {
        DoIt();
    }

    [Conditional("TRACE")]
    void DoIt()
    {
        Console.WriteLine("Did it.");
    }
}

这将使我的客户端代码在非 TRACE 构建中对“nop”TraceOnlyDoIt() 方法进行冗余调用。我可以在界面上使用条件扩展方法来解决这个问题,但它变得有点难看。

interface IFoo
{
    void TraceOnlyDoIt();
}

class Foo : IFoo
{
    public void TraceOnlyDoIt()
    {
        Console.WriteLine("Did it.");
    }
}

static class FooExtensions
{
    [Conditional("TRACE")]
    public static void DoIt(this IFoo foo)
    {
        foo.TraceOnlyDoIt();
    }
}

有更好的方法吗?

最佳答案

我喜欢扩展方法。它可以做得更好/更健壮,至少对于调用者而言:

    public interface IFoo
    {
        /// <summary>
        /// Don't call this directly, use DoIt from IFooExt
        /// </summary>
        [Obsolete]
        void DoItInternal();
    }

    public static class IFooExt
    {
        [Conditional("TRACE")]
        public static void DoIt<T>(this T t) where T : IFoo
        {
#pragma warning disable 612
            t.DoItInternal();
#pragma warning restore 612
        }
    }

    public class SomeFoo : IFoo
    {
        void IFoo.DoItInternal() { }

        public void Blah()
        {
            this.DoIt();
            this.DoItInternal(); // Error
        }
    }

通用类型约束用于避免虚拟调用和值类型的潜在装箱:优化器应该很好地处理这个问题。至少在 Visual Studio 中,如果您因为过时而调用内部版本,它会生成警告。显式接口(interface)实现用于防止意外调用具体类型的内部方法:用 [Obsolete] 标记它们也可以。

虽然这对于 Trace 的东西可能不是最好的主意,但在某些情况下这种模式很有用(我从一个不相关的用例中找到了我的方法)。

关于接口(interface)成员的 C# 条件属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5241700/

相关文章:

c# - Azure 上无法识别 WebAPI 路由

c# - typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(typeof(IList<>))

c# - Razor View 看不到 System.Web.Mvc.HtmlHelper

c# - .net 中的提供商模型

c# - 与#if/#endif 相比,条件属性的缺点是什么?

c# - 为什么我不能将 Debug.Assert() 与接受动态并返回 bool 的方法一起使用?

c# - 是否可以使用条件属性来创建类似的调试器和运行时方法?

c# - 在静态构造函数中初始化静态变量而不是直接赋值有什么好处