Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 静态列表中的对象生存期-对象的弱引用_C# - Fatal编程技术网

C# 静态列表中的对象生存期-对象的弱引用

C# 静态列表中的对象生存期-对象的弱引用,c#,C#,目前我有以下课程 class BaseClass : IDisposable { private static List<BaseClass> instances = new List<BaseClass>(); protected BaseClass() { instances.Add(this); } ~BaseClass() { Dispose(); } public

目前我有以下课程

class BaseClass : IDisposable
{
    private static List<BaseClass> instances = new List<BaseClass>();

    protected BaseClass()
    {
        instances.Add(this);
    }
    ~BaseClass()
    {
        Dispose();
    }
    public void Dispose()
    {
        instances.Remove(this);
    }
}
如何让
DerivedClass
在正常生存期后调用其析构函数的行为(因为它不在列表中)


背景 我想用配置文件中的值填充派生类的属性,并在基类中完成。但是,如果配置文件发生更改,我必须更改所有L派生类的所有属性。因此,如果您知道一种获取所有实现基类且需要更改的对象的方法,请告诉我


更新 解决方案1:基于我的问题 在()的帮助下,我发现了如何使用几行代码进行弱引用:

class BaseClass : IDisposable
{
    private static List<GCHandle> handles = new List<GCHandle>();
    protected BaseClass()
    {
        this.handle = GCHandle.Alloc(this, GCHandleType.Weak);
        handles.Add(this.handle);
    }
    ~BaseClass()
    {
        Dispose();
    }
    public void Dispose()
    {
        if (handle.IsAllocated)
        {
            //Do Something more to Dispose the Object
            //...
            handle.Free();
            handles.Remove(handle);
        }
    }
    public void DoSomethingWithTheList()
    {
        foreach (GCHandle handle in handles)
        {
            BaseClass bc = (BaseClass)handle.Target;
            //Do something
        }
    }
}

当您的基类实例处于关闭状态时,即调用Dispose和实例本身被销毁时。这些情况是正常的。

当基类实例处于关闭状态时,即调用Dispose和实例本身被销毁时。这些情况是正常的。

如果看不到更多的程序,就很难确定您的方法是否可以改进。但是,在不从根本上改变您的设计的情况下,我将使用weakreference来跟踪您的对象。UpdateClasses方法用于模拟重新配置操作

class BaseClass : IDisposable
{
    private WeakReference<BaseClass> myReference;
    private static List<WeakReference<BaseClass>> instances = new List<WeakReference>();

    public static UpdateClasses(MyData stuff)
    {
        foreach(var ref in instances)
        {
           BaseClass target;
           if (ref.TryGetTarget(out target))
           {
               // code to update target here
           }
        }
    }
    protected BaseClass()
    {
       myReference = new WeakReference<BaseClass>(this,true);
       instances.Add(myReference);
    }

    ~BaseClass()
    {
       Dispose();
    }

    public void Dispose()
    {
       instances.Remove(myReference);
    }
}
类基类:IDisposable
{
私人WeakReference myReference;
私有静态列表实例=新列表();
公共静态更新类(MyData stuff)
{
foreach(实例中的var ref)
{
基类目标;
如果(参考TryGetTarget(目标外))
{
//在此更新目标的代码
}
}
}
受保护基类()
{
myReference=新的WeakReference(这是真的);
实例。添加(myReference);
}
~BaseClass()
{
处置();
}
公共空间处置()
{
实例。删除(myReference);
}
}

弱引用将无法使对象保持活动状态。当它们被垃圾回收时,它们将从实例列表中删除它们的引用。但是,请注意,由于对终结器的要求,此实现将导致对象在垃圾收集器中的活动时间比正常时间长,随着时间的推移,这可能会降低应用程序的性能。

如果看不到更多的程序,则很难确定您的方法是否可以改进。但是,在不从根本上改变您的设计的情况下,我将使用weakreference来跟踪您的对象。UpdateClasses方法用于模拟重新配置操作

class BaseClass : IDisposable
{
    private WeakReference<BaseClass> myReference;
    private static List<WeakReference<BaseClass>> instances = new List<WeakReference>();

    public static UpdateClasses(MyData stuff)
    {
        foreach(var ref in instances)
        {
           BaseClass target;
           if (ref.TryGetTarget(out target))
           {
               // code to update target here
           }
        }
    }
    protected BaseClass()
    {
       myReference = new WeakReference<BaseClass>(this,true);
       instances.Add(myReference);
    }

    ~BaseClass()
    {
       Dispose();
    }

    public void Dispose()
    {
       instances.Remove(myReference);
    }
}
类基类:IDisposable
{
私人WeakReference myReference;
私有静态列表实例=新列表();
公共静态更新类(MyData stuff)
{
foreach(实例中的var ref)
{
基类目标;
如果(参考TryGetTarget(目标外))
{
//在此更新目标的代码
}
}
}
受保护基类()
{
myReference=新的WeakReference(这是真的);
实例。添加(myReference);
}
~BaseClass()
{
处置();
}
公共空间处置()
{
实例。删除(myReference);
}
}

弱引用将无法使对象保持活动状态。当它们被垃圾回收时,它们将从实例列表中删除它们的引用。但是,请注意,由于终结器的要求,此实现将导致您的对象在垃圾收集器中的存活时间比正常情况下更长,这可能会随着时间的推移降低应用程序的性能。

尽管Steve Mitchman给出了答案,您可以设计一个广播器类,该类提供一个事件,每当检测到配置文件中的更改时就会触发该事件。派生类(对象)可以订阅此事件,并在收集或最终确定get GC时取消订阅。这种方法很好地遵循了打开/关闭原则。

尽管Steve Mitchman给出了答案,但您可以设计一个广播器类,该类提供一个事件,只要检测到配置文件中的更改,就会触发该事件。派生类(对象)可以订阅此事件,并在收集或最终确定get GC时取消订阅。这种方法很好地遵循了打开/关闭原则。

为什么要手动保留正在创建的对象的实例?请阅读最后一句。我必须处理所有对象的各种操作。如果您知道另一种方法,请随意解释。每当您不想在内存中保存此静态列表时,请设置
instances=null
。@MitjaS。请原谅我的理论信息。您的需求看起来像发布者/订阅者模式。您可以有一个单独的对象来保存您的配置,并让您的所有子类订阅该对象以进行任何更改。使用您的替代解决方案,只有在显式处理的情况下,派生类才会被清除(这不一定是错误的,只是使用上的警告)。为什么要手动保留正在创建的对象的实例?请阅读最后一句。我必须处理所有对象的各种操作。如果您知道另一种方法,请随意解释。每当您不想在内存中保存此静态列表时,请设置
instances=null
。@MitjaS。请原谅我的理论信息。您的需求看起来像发布者/订阅者模式。你可以有一个单独的对象来保存你的配置,并让你的所有子类订阅它以进行任何更改。使用你的替代解决方案,派生类只有在显式释放时才会被清除(这不一定是错误的,只是用法上的一个警告)。我知道正常情况。我需要一个调整来获得对所有派生对象的访问,而不改变它们的生存期。我知道正常情况。我需要一个调整来访问所有派生对象,而不改变它们的生存期。我可以在这里找到的WeakReference有很多类。但这正是我想要的
class BaseClass : IDisposable
{
    private WeakReference<BaseClass> myReference;
    private static List<WeakReference<BaseClass>> instances = new List<WeakReference>();

    public static UpdateClasses(MyData stuff)
    {
        foreach(var ref in instances)
        {
           BaseClass target;
           if (ref.TryGetTarget(out target))
           {
               // code to update target here
           }
        }
    }
    protected BaseClass()
    {
       myReference = new WeakReference<BaseClass>(this,true);
       instances.Add(myReference);
    }

    ~BaseClass()
    {
       Dispose();
    }

    public void Dispose()
    {
       instances.Remove(myReference);
    }
}