下面的代码示例演示如何使用弱引用将对象的缓存作为应用程序的资源进行维护。此缓存是使用以索引值为关键字的 WeakReference 对象的 IDictionary<(Of <(TKey, TValue>)>) 构建的。WeakReference 对象的 Target 属性是一个表示数据的字节数组中的对象。此示例将随机访问缓存中的对象。如果通过垃圾回收来回收对象,则将重新生成新的数据对象;否则,该对象会因弱引用而可访问。using System; using System.Collections.Generic;public class Program { public static void Main() { // Create the cache. int cacheSize = 50; Random r = new Random(); Cache c = new Cache(cacheSize); string DataName = ""; // Randomly access objects in the cache. for (int i = 0; i < c.Count; i++) { int index = r.Next(c.Count); // Access the object by // getting a property value. DataName = c[index].Name; } // Show results. double regenPercent = c.RegenerationCount * 100 / c.Count; Console.WriteLine("Cache size: {0}, Regenerated: {1}%", c.Count.ToString(), regenPercent.ToString()); } } public class Cache { // Dictionary to contain the cache. static Dictionary<int, WeakReference> _cache; // Track the number of times an // object is regenerated. int regenCount = 0; public Cache(int count) { _cache = new Dictionary<int, WeakReference>(); // Add data objects with a // short weak reference to the cache. for (int i = 0; i < count; i++) { _cache.Add(i, new WeakReference(new Data(i), false)); } } // Returns the number of items in the cache. public int Count { get { return _cache.Count; } } // Returns the number of times an // object had to be regenerated. public int RegenerationCount { get { return regenCount; } } // Accesses a data object from the cache. // If the object was reclaimed for garbage collection, // create a new data object at that index location. public Data this[int index] { get { // Obtain an instance of a data // object from the cache of // of weak reference objects. Data d = _cache[index].Target as Data; if (d == null) { // Object was reclaimed, so generate a new one. Console.WriteLine("Regenerate object at {0}: Yes", index.ToString()); d = new Data(index); regenCount++; } else { // Object was obtained with the weak reference. Console.WriteLine("Regenerate object at {0}: No", index.ToString()); } return d; } }} // This class creates byte arrays to simulate data. public class Data { private byte[] _data; private string _name; public Data(int size) { _data = new byte[size * 1024]; _name = size.ToString(); } // Simple property. public string Name { get { return _name; } }}// Example of the last lines of the output: // // ... // Regenerate object at 36: Yes // Regenerate object at 8: Yes // Regenerate object at 21: Yes // Regenerate object at 4: Yes // Regenerate object at 38: No // Regenerate object at 7: Yes // Regenerate object at 2: Yes // Regenerate object at 43: Yes // Regenerate object at 38: No // Cache size: 50, Regenerated: 94% //
还是没怎么看明白。你看下这样的回答是否符合你的要求? class Person { public string ID; public string name; }class Student : Person { public stuID; }class SuperStudent : Student { public PhoneNum; }//使用的时候 SuperSutdent spStudent = new SuperStudent(); spStudent.stuID = "10011010"; spStuDent.PhoneNum = "130000000"; ...
因为如果对象保存在dictionary里面,
就不会被回收了。使用夸张方法,动态添加属性是什么意思?
能不能详细谈谈
GC.Collect(); //强制进行垃圾回收
List<T>释放
动态添加类属性,要4.0版本的动态类
既然对象作为key保存了,
那垃圾回收自然不认为他不被使用咯。
需要显示的在Dispose里面进行释放。
那么只要dictionary不被回收,
他的key自然也不会回收。
大家想想是不是这个理
另外添加属性还有一个方法,你可以继成该类,产生一个派生类,这样就可以再添加一个属性了。还有一种让引用存在的情况下也可以垃圾回收的方法,叫做弱引用。将student对象设置为弱引用时,它将在任何时刻都可以被垃圾回收,无视其是否被引用。
字典的话,不知道什么时候student不使用,所以也就不知道什么时候要去移除key。
派生类的话,不复核要求,要求就是对象级别上的,而且不知道是什么类型的对象。最后一个弱引用,能不能详细说说,我现在就去查资料。
using System.Collections.Generic;public class Program
{ public static void Main()
{ // Create the cache.
int cacheSize = 50;
Random r = new Random();
Cache c = new Cache(cacheSize); string DataName = ""; // Randomly access objects in the cache.
for (int i = 0; i < c.Count; i++)
{
int index = r.Next(c.Count); // Access the object by
// getting a property value.
DataName = c[index].Name;
}
// Show results.
double regenPercent = c.RegenerationCount * 100 / c.Count;
Console.WriteLine("Cache size: {0}, Regenerated: {1}%", c.Count.ToString(), regenPercent.ToString()); }
}
public class Cache
{
// Dictionary to contain the cache.
static Dictionary<int, WeakReference> _cache; // Track the number of times an
// object is regenerated.
int regenCount = 0; public Cache(int count)
{ _cache = new Dictionary<int, WeakReference>(); // Add data objects with a
// short weak reference to the cache.
for (int i = 0; i < count; i++)
{
_cache.Add(i, new WeakReference(new Data(i), false));
} } // Returns the number of items in the cache.
public int Count
{
get
{
return _cache.Count;
}
} // Returns the number of times an
// object had to be regenerated.
public int RegenerationCount
{
get
{
return regenCount;
}
} // Accesses a data object from the cache.
// If the object was reclaimed for garbage collection,
// create a new data object at that index location.
public Data this[int index]
{
get
{
// Obtain an instance of a data
// object from the cache of
// of weak reference objects.
Data d = _cache[index].Target as Data;
if (d == null)
{
// Object was reclaimed, so generate a new one.
Console.WriteLine("Regenerate object at {0}: Yes", index.ToString());
d = new Data(index);
regenCount++;
}
else
{
// Object was obtained with the weak reference.
Console.WriteLine("Regenerate object at {0}: No", index.ToString());
} return d;
} }}
// This class creates byte arrays to simulate data.
public class Data
{
private byte[] _data;
private string _name; public Data(int size)
{
_data = new byte[size * 1024];
_name = size.ToString();
} // Simple property.
public string Name
{
get
{
return _name;
}
}}// Example of the last lines of the output:
//
// ...
// Regenerate object at 36: Yes
// Regenerate object at 8: Yes
// Regenerate object at 21: Yes
// Regenerate object at 4: Yes
// Regenerate object at 38: No
// Regenerate object at 7: Yes
// Regenerate object at 2: Yes
// Regenerate object at 43: Yes
// Regenerate object at 38: No
// Cache size: 50, Regenerated: 94%
//
class Person
{
public string ID;
public string name;
}class Student : Person
{
public stuID;
}class SuperStudent : Student
{
public PhoneNum;
}//使用的时候
SuperSutdent spStudent = new SuperStudent();
spStudent.stuID = "10011010";
spStuDent.PhoneNum = "130000000";
...
现在对弱引用有了解了。但是如何实现我的目的呢?
比如实现这样的方法:int getNo(Student stu){???}
void setNo(Student stu,int no){???}然而student没有No这个的属性。
这时候后这两个方法的内部应该整么写?
Dictionary<WeakReference, int> cache = new Dictionary<WeakReference, int>();
/// <summary>
/// 将Student对象及其对应的no值缓存,只要外部还存在对stu的其它引用,缓存将一直有效。
/// </summary>
/// <param name="stu"></param>
/// <param name="no"></param>
void setNo(Student stu,int no)
{
WeakReference weak = findNullTag();
if (weak == null)
{
weak = new WeakReference(stu, false);
cache.Add(weak, no);
}
else
{
weak.Target = stu;
cache[weak] = no;
}
} /// <summary>
/// 查找可再利用的WeakReference对象。
/// </summary>
/// <returns></returns>
WeakReference findNullTag()
{
foreach (WeakReference key in cache.Keys)
{
if (key.Target == null)
{
return key;
}
}
return null;
} /// <summary>
/// 如果没有找到,则返回-1。
/// </summary>
/// <param name="stu"></param>
/// <returns></returns>
int getNo(Student stu)
{
foreach (WeakReference key in cache.Keys)
{
if (key.Target == stu)
{
return cache[key];
}
}
return -1;
}
var obj = new { new Student("Jill"), PhoneID = "110" };
//使用的时候
Console.WriteLine("{0},{1}", obj.Studeng, obj.PhoneID);
谢谢你负责的精神。
这个问题我们还可以继续讨论。这段代码中,虽然stu对象应该是能够成功被回收了。
但是我琢磨着保存在Dictionary<WeakReference, int> cache里面的,
包括WeakReference,和那些对应的int,不能够随着stu对象回收而回收吧。
或者这里面有什么玄机,我没看出来本人以为,这样还是不行。
因为不管这个匿名类是什么东西,
还想要得到,stu对应的no,
总要保存这个对象obj吧。既然保存这obj,那么作为obj属性的,
stu自然也被保存了,
垃圾回收,依然不会进行吧。