有没有办法绕过私有关键字?

时间:2013-12-30 19:16:16

标签: c# .net

我有一堆用于调试目的的代码。因此,我用它包围它:

#if DEBUG
#endif

问题是这个调试代码需要将私有变量从其他类输出到文件。我可以将调试代码隐藏到每个类中,但这会使现有代码更加混乱,因为我将调试代码与实际代码混合在一起。我可以将所有调试代码放到另一个类中,但这意味着我必须在类public中创建私有变量。

为了调试代码,有没有办法忽略private关键字?我可以使用公共getter,但这样做的目的是不使真正的代码更加混乱。

2 个答案:

答案 0 :(得分:2)

  1. 是否可以将它们设为内部而非私有?
  2. 使用dynamic关键字:

    dynamic foo = yourObjectWithPrivateFields; int privateValue =(int)foo.yourPrivateField;

  3. 使用反思:typeof(YourObject).GetField(fieldName, bindFlags).GetValue(yourObjectWithPrivateFields);

答案 1 :(得分:1)

使用Reflection作为filoe建议可能是解决这个特定问题的最佳方法。

为了说明解决OP所询问的代码组织问题的一种方法,我提供了另一种方法的示例。这可能不是解决希望从私有成员记录数据以进行调试的问题的理想方法,但它演示了使用部分类组织代码以及使用嵌套类以便为外部代码提供访问私有的方法成员。

    // This MyClass code goes into a MyClass.cs file
    public partial class MyClass
    {
        private int fieldA;

        private string fieldB;

        private decimal fieldC;

        public MyClass(int a, string b, decimal c)
        {
            this.fieldA = a;
            this.fieldB = b;
            this.fieldC = c;
        }
    }

    // This additional code for MyClass goes into a
    // separate MyClass.debug.cs file
#if DEBUG

    partial class MyClass : IDebugAccessible
    {
        public IDebugAccessor GetDebugAccessor()
        {
            return new DebugAccessor(this);
        }

        // The MyClass.DebugAccessor nested class has access to
        // private members of MyClass.
        private class DebugAccessor : IDebugAccessor
        {
            private MyClass instance;

            public DebugAccessor(MyClass instance)
            {
                this.instance = instance;
            }

            public IEnumerable<KeyValuePair<string, object>> Values
            {
                get
                {
                    return new Dictionary<string, object>
                    {
                        { "fieldA", instance.fieldA },
                        { "fieldB", instance.fieldB },
                        { "fieldC", instance.fieldC },
                    };
                }
            }
        }
    }

#endif

    // The intention behind creating these interfaces is to define
    // a standard way to access values from different types
    // for debugging purposes.  This is just a simple example.
    // These interfaces would go into their own .cs file.
    public interface IDebugAccessor
    {
        IEnumerable<KeyValuePair<string, object>> Values { get; }
    }

    public interface IDebugAccessible
    {
        IDebugAccessor GetDebugAccessor();
    }