C# 计算类方法中类类型对象的数量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1168746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:53:32  来源:igfitidea点击:

Count number of objects of class type within class method

c#classobjectcountmethods

提问by Nona Urbiz

How can I count the number of objects of a class type within a method of that class? For that matter, how to do it outside of a class without adding the objects to a list?

如何在该类的方法中计算该类类型的对象数量?就此而言,如何在不将对象添加到列表的情况下在类之外执行此操作?

I should have thought of that! Thanks! I'm gonna leave it unanswered for a little while to see if there is a better way, because I agree. I'm just sortv wrapping my head around OO. If you don't mind let me explain a little more and maybe there is a better way in general?

我早该想到的!谢谢!我将暂时不回答它,看看是否有更好的方法,因为我同意。我只是把我的头围绕在 OO 上。如果你不介意让我多解释一点,也许有更好的方法?

I have an object class that i want to add 3 pieces of information to, but first I want to cycle through and make sure there are no other objects with any of the three pieces the same, and if there are, do something different for each case.

我有一个对象类,我想向其中添加 3 条信息,但首先我想循环并确保没有其他对象与这三条中的任何一条相同,如果有,则为每个对象做一些不同的事情案件。

采纳答案by Adam Robinson

The only way to accomplish what you're looking for is to keep a static list of these objects in the class itself. If you just want to see if there is an instance somewhere that hasn't been garbage collected, then you'll want to use the WeakReferenceclass. For example...

完成您正在寻找的唯一方法是在类本身中保留这些对象的静态列表。如果您只想查看某处是否有未被垃圾回收的实例,那么您将需要使用WeakReference该类。例如...

public class MyClass
{
    private static List<WeakReference> instances = new List<WeakReference>();

    public MyClass()
    {
         instances.Add(new WeakReference(this));
    }

    public static IList<MyClass> GetInstances()
    {
        List<MyClass> realInstances = new List<MyClass>();
        List<WeakReference> toDelete = new List<WeakReference>();

        foreach(WeakReference reference in instances)
        {
            if(reference.IsAlive)
            {
                realInstances.Add((MyClass)reference.Target);
            }
            else
            {
                toDelete.Add(reference);
            }
        }

        foreach(WeakReference reference in toDelete) instances.Remove(reference);

        return realInstances;
    }
}

Since you're new to OO/.NET, don't let the WeakReferenceuse scare you. The way garbage collection works is by reference counting. As long as some piece of code or an object has access to a particular instance (meaning it's within scope as a or as part of a local, instance, or static variable) then that object is considered alive. Once that variable falls OUT of scope, at some point after that the garbage collector can/will collect it. However, if you were to maintain a list of all references, they would never fall out of scope since they would exist as references in that list. The WeakReferenceis a special class allows you to maintain a reference to an object that the garbage collector will ignore. The IsAliveproperty indicates whether or not the WeakReferenceis pointing to a valid object that still exists.

由于您是 OO/.NET 的新手,所以不要让WeakReference使用吓到您。垃圾收集的工作方式是通过引用计数。只要某段代码或对象可以访问特定实例(意味着它作为局部、实例或静态变量的一部分或一部分在范围内),那么该对象就被认为是活动的。一旦该变量超出范围,垃圾收集器就可以/将收集它。但是,如果您要维护所有引用的列表,它们将永远不会超出范围,因为它们将作为该列表中的引用存在。这WeakReference是一个特殊的类,允许您维护对垃圾收集器将忽略的对象的引用。该IsAlive属性指示 是否WeakReference指向仍然存在的有效对象。

So what we do here is keep this list of WeakReferences that point to every instance of MyClassthat's been created. When you want to obtain a list of them, we iterate through our WeakReferences and snatch out all of them that are alive. Any we find that are no longer alive are placed into another temporary list so that we can delete them from our outer list (so that the WeakReferenceclass itself can be collected and our list doesn't grow huge without reason).

所以我们在这里做的是保留这个WeakReferences 的列表,这些s 指向MyClass已创建的每个实例。当你想获得它们的列表时,我们遍历我们的WeakReferences 并抢走所有活着的。我们发现不再存在的任何东西都被放入另一个临时列表中,以便我们可以从外部列表中删除它们(这样WeakReference可以收集类本身并且我们的列表不会无故变大)。

回答by Ed S.

You could implement some type of reference counting scheme, though I am not sure why you would want to do this. For every call to 'new' you can increment a counter, and you could then define a finalizer to decrement this value. There is probably a better, more robust way to do it, this was just off the top of my head.

您可以实现某种类型的引用计数方案,但我不确定您为什么要这样做。对于每次调用“new”,您可以增加一个计数器,然后您可以定义一个终结器来减少这个值。可能有更好,更强大的方法来做到这一点,这只是我的想法。

回答by Sam Harwell

I'm not exactly sure what you mean. But it might be this:

我不完全确定你的意思。但它可能是这样的:

MethodInfo methodInfo = ...;
MethodBody body = methodInfo.GetMethodBody();
int count = body.LocalVariables.Count(variable => variable.LocalType == typeof(DesiredType));

Another possibility: The profiler in Team Suite (and maybe others) can tell you:

另一种可能性:Team Suite(可能还有其他人)中的分析器可以告诉您:

  • The number of objects of type T allocated in every method
  • The number of bytesallocated in each method
  • 在每个方法中分配的类型 T 的对象数
  • 每种方法分配的字节

Edit: Due to the lack of a "dupn" or "swapn, n+1" IL instruction, the compiler is forced to generate locals you might not expect (ones you didn't explicitly declare). The compiler is also free to remove locals where possible when optimization is on.

编辑:由于缺少“ dupn”或“ swapn,n+1”IL 指令,编译器被迫生成您可能不期望的本地变量(您没有明确声明的那些)。当优化开启时,编译器也可以在可能的情况下自由地移除局部变量。

回答by Daniel Earwicker

Do you mean in a way that would allow you to track how many times you had called new MyClass()such that there are N instances taking up memory at the moment, and you want to know the value of N?

您的意思是让您可以跟踪您调用了多少次new MyClass(),以至于此时有 N 个实例占用了内存,并且您想知道 N 的值?

If you want to track memory usage, use the debugger to dump the state of the heap. The thing is, the answer will depend on the GC and whether it has collected unreferenced objects.

如果要跟踪内存使用情况,请使用调试器转储堆的状态。问题是,答案将取决于 GC 以及它是否收集了未引用的对象。

You could have a counter you increment in the constructor, but when to decrement it? Finalizers run in another thread, which underlines the unpredictability of this whole idea. Might be better to implement IDisposableto decrement the counter, and require the objects to be Disposed when not needed.

您可以在构造函数中增加一个计数器,但是什么时候减少它?终结器在另一个线程中运行,这突显了整个想法的不可预测性。实现IDisposable递减计数器可能会更好,并要求在不需要时处置对象。