1

我有一个简单的程序:

using System;
using System.Reflection;

namespace PlayWithReflection
{
class MyDisposable:IDisposable
{
    private  string _name;

    public MyDisposable(string name)
    {
        this._name = name;
    }

    public string Name
    {
        get { return _name; }
    }

    public void Dispose()
    {
        Console.WriteLine(_name + " is disposed");
    }
}

class MyBaseClass : IDisposable
{
    protected MyDisposable _baseProtectedDisposableA = new MyDisposable("_baseProtectedDisposableA");
    private MyDisposable _baseDisposableB = new MyDisposable("_baseDisposableB");

    public MyDisposable BaseProtectedDisposableA
    {
        get { return _baseProtectedDisposableA; }
    }

    public MyDisposable BaseDisposableB
    {
        get { return _baseDisposableB; }
    }

    public void Dispose()
    {
        var fieldInfos = this.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

        foreach (var fieldInfo in fieldInfos)
        {
            var value = fieldInfo.GetValue(this);
            if (value is IDisposable)
            {
                ((IDisposable)value).Dispose();
                fieldInfo.SetValue(this, null);
            }
        }
    }
}


class MyClass : MyBaseClass
{
    private MyDisposable _disposableC = new MyDisposable("_disposableC");
    private MyDisposable _disposableD = new MyDisposable("_disposableD");

    public MyDisposable DisposableC
    {
        get { return _disposableC; }
    }

    public MyDisposable DisposableD
    {
        get { return _disposableD; }
    }
}



class Program
{
    static void Main(string[] args)
    {
        using(MyBaseClass instance = new MyClass())
        {
           Console.WriteLine(instance.BaseProtectedDisposableA.Name + " is telling his name...");
           Console.WriteLine("--------------------------------------------------------");
        }

        Console.ReadKey();
    }
}
}

它打印出这样的东西:

_baseProtectedDisposableA is telling his name...
-------------------------------------------------------
_disposableC is disposed
_disposableD is disposed
_baseProtectedDisposableA is disposed

问题是如何让它打印这个:

_baseProtectedDisposableA is telling his name...
-------------------------------------------------------
_disposableC is disposed
_disposableD is disposed
_baseProtectedDisposableA is disposed
_baseDisposableB is disposed

或者,换句话说,我的私有字段 _baseDisposableB 在哪里,以及如何处理它?

谢谢你。

4

2 回答 2

1

我的私人领域 _baseDisposableB 在哪里

阅读有关BindingFlags枚举的文档:

FlattenHierarchy 指定应返回层次结构上的公共和受保护静态成员。不返回继承类中的私有静态成员。静态成员包括字段、方法、事件和属性。不返回嵌套类型。

所以基类的私有成员不会被返回。这是有道理的,因为不应该从派生类访问私有成员。

如何使其被处置?

由于无论如何访问私有成员都是一种技巧,我不会尝试从派生类中处理它。我会Dispose直接在基类中明确显示它:

public void Dispose()
{
    var fieldInfos = this.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

    foreach (var fieldInfo in fieldInfos)
    {
        var value = fieldInfo.GetValue(this);
        if (value is IDisposable)
        {
            ((IDisposable)value).Dispose();
            fieldInfo.SetValue(this, null);
        }
    }
    _baseDisposableB.Dispose();
}

虽然我认为你有一些理由想要使用反射而不是明确地处置成员......

于 2012-11-08T14:16:12.223 回答
0

使用 . 获取基本类型的私有字段是不可能的GetType().GetFields(...)。您必须从基本类型本身获取字段。

示例:用以下两种方法替换您的Dispose方法:

public void Dispose()
{
    var type = GetType();
    while (type != null)
    {
        DisposeFields(type);
        type = type.BaseType;
    }
}

private void DisposeFields(Type type)
{
    var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

    foreach (var fieldInfo in fieldInfos)
    {
        var value = fieldInfo.GetValue(this) as IDisposable;
        if (value == null) continue;

        value.Dispose();
        fieldInfo.SetValue(this, null);
    }
}

这将通过继承层次结构和Dispose基本类型的字段(如果它们是一次性的)。

结果:

_baseProtectedDisposableA is telling his name...
--------------------------------------------------------
_disposableC is disposed
_disposableD is disposed
_baseProtectedDisposableA is disposed
_baseDisposableB is disposed
于 2012-11-08T14:19:01.903 回答