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来说绝对是一个好情况。