C# 在c中对类型的每个实例调用方法#

C# 在c中对类型的每个实例调用方法#,c#,types,methods,instance,C#,Types,Methods,Instance,我知道您可以调用一个实例方法,该方法对每个对象执行。我还知道,您可以对该类型使用静态方法,该方法可以从该类型调用 但是,如何调用作用于特定类型的每个实例的方法(例如,将成员变量设置为零)?如果您可以修改您正在谈论的类型,您可以在该类中创建一个静态列表,在其中保留所创建的每个对象的引用 当你运行你的方法时,你只需要循环所有的列表,然后运行你想要的 如果您无法修改该类型以便创建此列表,那么如果没有一些技巧,您就无法完成此操作,我建议您使用,这样您仍然可以保留该类型对象的列表,前提是您使用该工厂 注意

我知道您可以调用一个实例方法,该方法对每个对象执行。我还知道,您可以对该类型使用静态方法,该方法可以从该类型调用


但是,如何调用作用于特定类型的每个实例的方法(例如,将成员变量设置为零)?

如果您可以修改您正在谈论的类型,您可以在该类中创建一个静态列表,在其中保留所创建的每个对象的引用

当你运行你的方法时,你只需要循环所有的列表,然后运行你想要的

如果您无法修改该类型以便创建此列表,那么如果没有一些技巧,您就无法完成此操作,我建议您使用,这样您仍然可以保留该类型对象的列表,前提是您使用该工厂

注意:如果您不打算使用[]运算符(我的意思是通过索引)访问列表,而只是通过foreach访问列表,我建议您使用在这种情况下效率更高的方法(大量添加/删除操作,无需随机访问,并且可以避免像列表那样调整数组大小)

示例:

using System.Linq.Expressions;

class MyClassFactory
{
    LinkedList<MyClass> m_Instances = new LinkedList<MyClass>();

    MyClass Create()
    {
        m_Instances.AddLast(new MyClass());
        return m_Instances.Last.Value;
    }

    void Destroy(MyClass obj)
    {
        m_Instances.Remove(obj);
    }

    void Execute(Expression<Action<MyClass, object>> expr, object param)
    {
        var lambda = expr.Compile();
        foreach (var obj in m_Instances)
            lambda(obj, param);
    }
}
使用System.Linq.Expressions;
类MyClassFactory
{
LinkedList m_实例=新建LinkedList();
MyClass创建()
{
m_Instances.AddLast(新的MyClass());
返回m_Instances.Last.Value;
}
无效销毁(MyClass obj)
{
m_实例。移除(obj);
}
void Execute(表达式)要在所有这些实例上执行方法,还有其他方法,但这很好:

MyFactory f = new MyFactory();
for (int i = 0; i < 5; i++)
    f.Create();
f.Execute((obj, param) =>
{
    //Do something
}, null);
MyFactory f=newmyfactory();
对于(int i=0;i<5;i++)
f、 创建();
f、 执行((对象,参数)=>
{
//做点什么
},空);
*编辑:*(关于Ben Voigt评论)

方法,继续使用垃圾收集:

using System.Linq.Expressions;

class MyClassFactory
{
    HashSet<WeakReference> m_Instances = new HashSet<WeakReference>();

    MyClass Create()
    {
        var obj = new MyClass();
        m_Instances.Add(new WeakReference(obj));
        return obj;
    }

    void Execute(Expression<Action<MyClass, object>> expr, object param)
    {
        var lambda = expr.Compile();
        // Hope syntax is ok on this line
        m_Instances.RemoveWhere(new Predicate<WeakReference>(obj => !obj.IsAlive));

        foreach (var obj in m_Instances)
            lambda(obj, param);
    }
}
使用System.Linq.Expressions;
类MyClassFactory
{
HashSet m_Instances=新HashSet();
MyClass创建()
{
var obj=新的MyClass();
添加(新的WeakReference(obj));
返回obj;
}
void Execute(查看其用法的表达式)

C#没有提供跟踪所有可访问对象的直接机制,而且几乎没有任何理由需要这种自动跟踪功能(而不是,比方说,您自己管理的显式池)

但要直接满足您的要求,您需要:

  • 手动跟踪该类型的所有可访问实例(可能使用一组弱引用来防止跟踪器本身延长对象的生命周期)
  • 提供一种机制来(比如)对这个集合中的每个成员产生副作用
  • 当对象被销毁时,从集合中删除关联的弱引用。这是防止弱引用泄漏所必需的
  • 所有这些都必须以线程安全的方式完成

    public class Foo
    {
        private static readonly HashSet<WeakReference> _trackedFoos = new HashSet<WeakReference>();
        private static readonly object _foosLocker = new object();
    
        private readonly WeakReference _weakReferenceToThis;
    
        public static void DoForAllFoos(Action<Foo> action)
        {
            if (action == null)
                throw new ArgumentNullException("action");
    
            lock (_foosLocker)
            {
                foreach (var foo in _trackedFoos.Select(w => w.Target).OfType<Foo>())
                    action(foo);
            }
        }
    
        public Foo()
        {
           _weakReferenceToThis = new WeakReference(this);
    
            lock (_foosLocker)
            {
                _trackedFoos.Add(_weakReferenceToThis);
            }
        }
    
        ~Foo()
        {
            lock (_foosLocker)
            {
                _trackedFoos.Remove(_weakReferenceToThis);
            }
        }
    }
    
    公共类Foo
    {
    私有静态只读哈希集_trackedFoos=new HashSet();
    私有静态只读对象_foosLocker=new object();
    私有只读WeakReference\u weakReferenceToThis;
    公共静态无效DoForAllFoos(操作)
    {
    if(action==null)
    抛出新的异常(“操作”);
    锁(_foosLocker)
    {
    foreach(在_trackedFoos.Select(w=>w.Target.OfType()中的var foo)
    行动(foo);
    }
    }
    公共食物(
    {
    _weakReferenceToThis=新的WeakReference(this);
    锁(_foosLocker)
    {
    _trackedFoos.Add(_weakReferenceToThis);
    }
    }
    ~Foo()
    {
    锁(_foosLocker)
    {
    _trackedFoos.Remove(_weakReferenceToThis);
    }
    }
    }
    

    你确定你需要所有这些吗?这真的很奇怪而且不确定(会受到垃圾收集发生时的严重影响)。

    你不清楚你的意思。你能提供一个例子吗?向对象发送非静态方法的唯一方法是指定目标对象。C#/.NET不会自动跟踪“类型X的所有实例”。通常,一个实例有一个对象集合,例如,
    List myItems=…
    ,然后对所有适用的元素执行操作,例如
    foreach(myItems中的var item){item.ClearIt();}
    。请注意,项需要手动放入
    myItems
    。简而言之,您不能。如果类型是类,也许您可以跟踪构造函数中的实例,并创建一个静态方法来处理每个实例。@TomislavMarkovski:我很确定,使用托管调试API,您可以找到某个特定对象的所有实例Ar类。但是它会很难处理。这会破坏垃圾回收。有一个销毁方法,这是一个工厂应该如何工作。如果你不删除这些实例,那就是你的错。如果你不调用C++中的删除,你会给堆堆造成问题,这里是一样的。需要手动销毁每个实例是相反的。我更喜欢这种方法,但是我提供了一种弱引用方法。因为他不需要搜索任何对象:他说“我必须在一个类的所有实例上运行一个方法“。也就是说,如果他说必须循环所有链接,我不明白他为什么需要搜索它们。如果他喜欢创建/销毁方法,这对LinkedList来说绝对是一个好情况。