ConditionalWeakTable<TKey, TValue>使编译器可以将对象字段动态附加到托管对象。
2015-08-13 00:23
721 查看
MSDN关于它的介绍:https://msdn.microsoft.com/zh-cn/library/dd287757(v=vs.100).aspx
先看一个小demo:
=========Using Fixed Data==========
value of Person is : Age 1, Name: demoPerson
=========Using Dictionary==========
value of Person is : Age 2, Name: demoPerson2
有几点要注意下:
ConditionalWeakTable<TKey, TValue> 类使得语言编译器可在运行时给托管的对象附加任意属性。ConditionalWeakTable<TKey,
TValue> 对象是一个字典,它将一个键表示的托管对象绑定到一个值表示的附加属性。 该对象的键是 TKey 类的个体实例,属性附加到这个类上,且其值为分配到相应对象的属性值。
键必须唯一;换句话说,ConditionalWeakTable<TKey, TValue> 类支持每个托管对象一个附加值。 如果将两个键传递给 Object.ReferenceEquals 方法返回 true,这两个键相等。
尽管 ConditionalWeakTable<TKey, TValue> 类保存键/值对的集合,最好将其视为表而不是字典对象。ConditionalWeakTable<TKey,
TValue> 类在几个方面与字典不同:
它不保留键。 也就是说,键不会只是因为它是集合的成员而保持活动状态。
它并不能包括词典通常包含的所有方法(如 GetEnumerator 或 Contains)。
它未实现 IDictionary<TKey, TValue> 接口。
先看一个小demo:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.CompilerServices; namespace ExtensionProps { public class Person { } public class SomeClass { } public class ExtraPersonProps { public int Age { get; private set; } public string Name { get; private set; } public ExtraPersonProps(int age, string name) { Age = age; Name = name; } } class Program { static void Main(string[] args) { Console.WriteLine("=========Using Fixed Data==========\r\n"); //demo with fixed data ConditionalWeakTable<Person, ExtraPersonProps> cwtPerson = new ConditionalWeakTable<Person, ExtraPersonProps>(); Person p = new Person(); cwtPerson.Add(p, new ExtraPersonProps(1,"demoPerson")); ExtraPersonProps props; if (cwtPerson.TryGetValue(p, out props)) Console.WriteLine(string.Format("value of Person is : Age {0}, Name: {1}", props.Age, props.Name)); Console.WriteLine("=========Using Dictionary==========\r\n"); //demo with Dictonary data ConditionalWeakTable<Person, Dictionary<string, object>> cwtPerson2 = new ConditionalWeakTable<Person, Dictionary<string, object>>(); Person p2 = new Person(); Dictionary<string, object> data = new Dictionary<string, object>(); data.Add("age", 2); data.Add("name", "demoPerson2"); cwtPerson2.Add(p2, data); Dictionary<string, object> dataRetrieved; if (cwtPerson2.TryGetValue(p2, out dataRetrieved)) Console.WriteLine(string.Format("value of Person is : Age {0}, Name: {1}", dataRetrieved["age"], dataRetrieved["name"])); Console.ReadLine(); } } }Which outputs this
=========Using Fixed Data==========
value of Person is : Age 1, Name: demoPerson
=========Using Dictionary==========
value of Person is : Age 2, Name: demoPerson2
有几点要注意下:
ConditionalWeakTable<TKey, TValue> 类使得语言编译器可在运行时给托管的对象附加任意属性。ConditionalWeakTable<TKey,
TValue> 对象是一个字典,它将一个键表示的托管对象绑定到一个值表示的附加属性。 该对象的键是 TKey 类的个体实例,属性附加到这个类上,且其值为分配到相应对象的属性值。
键必须唯一;换句话说,ConditionalWeakTable<TKey, TValue> 类支持每个托管对象一个附加值。 如果将两个键传递给 Object.ReferenceEquals 方法返回 true,这两个键相等。
尽管 ConditionalWeakTable<TKey, TValue> 类保存键/值对的集合,最好将其视为表而不是字典对象。ConditionalWeakTable<TKey,
TValue> 类在几个方面与字典不同:
它不保留键。 也就是说,键不会只是因为它是集合的成员而保持活动状态。
它并不能包括词典通常包含的所有方法(如 GetEnumerator 或 Contains)。
它未实现 IDictionary<TKey, TValue> 接口。
using System; using System.Runtime.CompilerServices; public class Example { public static void Main() { var mc1 = new ManagedClass(); var mc2 = new ManagedClass(); var mc3 = new ManagedClass(); var cwt = new ConditionalWeakTable<ManagedClass, ClassData>(); cwt.Add(mc1, new ClassData()); cwt.Add(mc2, new ClassData()); cwt.Add(mc3, new ClassData()); var wr2 = new WeakReference(mc2); mc2 = null; GC.Collect(); ClassData data = null; if (wr2.Target == null) Console.WriteLine("No strong reference to mc2 exists."); else if (cwt.TryGetValue(mc2, out data)) Console.WriteLine("Data created at {0}", data.CreationTime); else Console.WriteLine("mc2 not found in the table."); } } public class ManagedClass { } public class ClassData { public DateTime CreationTime; public object Data; public ClassData() { CreationTime = DateTime.Now; this.Data = new object(); } } // The example displays the following output: // No strong reference to mc2 exists.
using System; using System.Runtime.CompilerServices; using System.Threading; public class ManagedObject { } public class AttachedProperty { public AttachedProperty(ManagedObject obj, int ctr) { this.obj = obj; this.ctr = ctr; } public int ctr; public ManagedObject obj; } public class Example { public static void Main() { // Create two managed objects. ManagedObject m1 = new ManagedObject(); ManagedObject m2 = new ManagedObject(); // Define their attached property values. AttachedProperty p1 = new AttachedProperty(null, 0); AttachedProperty p2 = new AttachedProperty(m1, 1); // Create the table and add the key/value pairs. var table = new ConditionalWeakTable<ManagedObject, AttachedProperty>(); table.Add(m1, p1); table.Add(m2, p2); // Destroy m1. m1 = null; // Sleep for 1 second to allow m1 to be garbage collected. Thread.Sleep(1000); // Reinstantiate m1 m1 = new ManagedObject(); // Try to retrieve m1 and m2. AttachedProperty value = null; if (table.TryGetValue(m2, out value)) Console.WriteLine("m2: ({0}, {1})", value.obj, value.ctr); else Console.WriteLine("m2 is not in the table."); if (table.TryGetValue(m1, out value)) Console.WriteLine("m1: ({0}, {1})", value.obj, value.ctr); else Console.WriteLine("m1 is not in the table."); } } // The example displays the following output: // m2: (ManagedObject, 1) // m1 is not in the table.
相关文章推荐
- iOS的UILabel设置居上对齐,居中对齐,居下对齐
- Leetcode: Repeated DNA Sequences
- MySQL 5.6 中TIMESTAMP with implicit DEFAULT value is deprecated错误
- php中include()和require()的区别
- php中include()和require()的区别
- Implement Stack using Queues
- could not build module 'uikit'
- Java集合类: Set、List、Map、Queue使用场景梳理
- uva 1152 4 Values whose Sum is 0
- 【UITextField与UITextView】
- 【UISegmentedControl】
- HDU 3397 Sequence operation(区间合并 + 区间更新)
- Request Parameters and Header Values
- [LeetCode]Permutation Sequence
- OC-UI部分,简单的登陆界面简单代码
- Domino Angular 前端UI开发
- arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf、gnueabi区别
- DCIM 用 UIScrollView 和UIPageControl
- js实现EasyUI-datagrid前台分页
- Leetcode63 Unique Paths II