回答
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);
}
}
}
你確定你需要所有這些嗎?這真是奇怪而且不確定(當垃圾收集發生時會受到嚴重影響)。
如果您可以修改您正在討論的類型,則可以在該類中創建一個靜態列表,並在其中保存每個創建對象的引用。
當你運行你的方法時,你只需要遍歷所有的列表並運行你想要的。
如果你不能修改那個類型,所以你可以創建這個列表,你不能做到這一點沒有一些黑客,我可以建議你使用Factory pattern,所以你仍然可以保持該類型的對象列表,只要你使用那個工廠。
注意:如果你不打算只通過一個foreach訪問與[]運營商名單(通過索引我的意思),但是,我建議你使用一個LinkedList,這將是迄今爲止在這種情況下更有效(大量的添加/刪除操作,沒有隨機訪問,你會避免像列表一樣調整數組大小)。
例子:
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);
}
}
此後可以輕鬆地實例化,並始終使用該工廠來實例化類。 這不是一個完美的解決方案,但它是一個乾淨的方法,至少可以解決您的問題。
您可以使用lambda expressions在所有這些情況下執行的方法,也有其他的方法,但是那是美麗的:
MyFactory f = new MyFactory();
for (int i = 0; i < 5; i++)
f.Create();
f.Execute((obj, param) =>
{
//Do something
}, null);
* 編輯:*(約本福格特評論)
Weak reference方法,繼續使用垃圾回收:
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);
}
}
檢查RemoveWhere看到它的用法
這打破垃圾收集。 – 2011-12-23 05:03:19
有一種銷燬方法,這就是工廠應該如何工作。如果你不刪除這些實例,這是你的錯誤。如果你不用C++調用delete,你會在你的堆上創建問題,這裏是一樣的。 – 2011-12-23 05:06:50
要求手動銷燬每個實例與垃圾收集相反。 – 2011-12-23 05:08:59
- 1. 從同一類中的另一種方法在類實例中調用方法
- 2. 在Javascript中調用每個類的實例的方法?
- 3. C++類實例化和調用方法
- 4. 在調用它的實例類方法
- 5. 在C#中的類的實例方法中使用GetValue方法
- 6. 如何在實例類中的實例上調用方法?
- 7. 陣列中每個類實例的調用方法(Matlab)
- 8. 調用實例方法的實例方法調用實例方法
- 9. 實例化T調用方法中的類可調用類
- 10. 在javascript中調用實例創建回調的實例方法
- 11. 在數組中的每個對象上調用實例方法
- 12. 如何在類方法中調用不同的類實例?
- 13. 類與實例方法Obejctive-C調用 - NSLocale方法
- 14. C#調用泛型方法的類的每個領域
- 15. Objective-C類方法不調用委託方法而實例方法確實
- 16. 無法實例類型的實例在Java中的Weka類
- 17. 如何在C++中的實例中調用方法
- 18. 在用classFromString實例化的類中調用方法?
- 19. 自動調用每當一個實例被調用的方法
- 20. 在C#中使用泛型創建類似類型的實例
- 21. Objective C - 類方法,實例方法
- 22. 創建一個C++類的實例並在Python中調用它的方法
- 23. 每種測試方法中使用的技術類型
- 24. 調用同一實例的兩種方法是觸發WCF中的Dispose方法
- 25. 檢索從一個方法在C#中引用調用的類實例
- 26. 兩種不同方式的類型類的實例
- 27. 每個實例的內存池是否存在每種類型的缺點?
- 28. 在實例化線程中調用的實例方法
- 29. 在泛型方法中創建返回類型的實例
- 30. 這是一種在JavaScript中實例化類的方法嗎?
目前尚不清楚你的意思。你能提供一個例子嗎? – Ani 2011-12-23 04:36:48
將非靜態方法發送到對象的唯一方法是具有所述目標對象。 C#/ .NET不會自動跟蹤「類型X的所有實例」。通常有一個對象集合,比如'List myItems = ...',然後對所有可用的元素執行操作,比如'foreach(myItems中的var item){item.ClearIt(); }'。請注意,項目需要手動放入'myItems' *。 –
2011-12-23 04:37:30
簡短的回答,你不能。 – 2011-12-23 04:39:37