update MEF to preview 9
[mcs.git] / class / System.ComponentModel.Composition / src / ComponentModel / System / ComponentModel / Composition / ReflectionModel / LazyMemberInfo.cs
blob6b492cf73083b9e5ae03eb5651d01be16995bf8d
1 // -----------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // -----------------------------------------------------------------------
4 using System;
5 using System.Diagnostics.CodeAnalysis;
6 using System.Globalization;
7 using System.Linq;
8 using System.Reflection;
9 using System.Threading;
10 using Microsoft.Internal;
12 namespace System.ComponentModel.Composition.ReflectionModel
14 public struct LazyMemberInfo
16 private readonly MemberTypes _memberType;
17 private MemberInfo[] _accessors;
18 private readonly Func<MemberInfo[]> _accessorsCreator;
20 public LazyMemberInfo(MemberInfo member)
22 Requires.NotNull(member, "member");
23 EnsureSupportedMemberType(member.MemberType, "member");
25 this._accessorsCreator = null;
26 this._memberType = member.MemberType;
28 switch(this._memberType)
30 case MemberTypes.Property:
31 PropertyInfo property = (PropertyInfo)member;
32 Assumes.NotNull(property);
33 this._accessors = new MemberInfo[] { property.GetGetMethod(true), property.GetSetMethod(true) };
34 break;
35 case MemberTypes.Event:
36 EventInfo event_ = (EventInfo)member;
37 this._accessors = new MemberInfo[] { event_.GetRaiseMethod(true), event_.GetAddMethod(true), event_.GetRemoveMethod(true) };
38 break;
39 default:
40 this._accessors = new MemberInfo[] { member };
41 break;
45 public LazyMemberInfo(MemberTypes memberType, params MemberInfo[] accessors)
47 EnsureSupportedMemberType(memberType, "memberType");
48 Requires.NotNull(accessors, "accessors");
50 string errorMessage;
51 if (!LazyMemberInfo.AreAccessorsValid(memberType, accessors, out errorMessage))
53 throw new ArgumentException(errorMessage, "accessors");
56 this._memberType = memberType;
57 this._accessors = accessors;
58 this._accessorsCreator = null;
61 public LazyMemberInfo(MemberTypes memberType, Func<MemberInfo[]> accessorsCreator)
63 EnsureSupportedMemberType(memberType, "memberType");
64 Requires.NotNull(accessorsCreator, "accessorsCreator");
66 this._memberType = memberType;
67 this._accessors = null;
68 this._accessorsCreator = accessorsCreator;
71 public MemberTypes MemberType
73 get { return this._memberType; }
76 public MemberInfo[] GetAccessors()
78 if ((this._accessors == null) && (this._accessorsCreator != null))
80 MemberInfo[] accessors = this._accessorsCreator.Invoke();
82 string errorMessage;
83 if (!LazyMemberInfo.AreAccessorsValid(this.MemberType, accessors, out errorMessage))
85 throw new InvalidOperationException(errorMessage);
88 this._accessors = accessors;
91 return this._accessors;
94 public override int GetHashCode()
96 if (this._accessorsCreator != null)
98 return this.MemberType.GetHashCode() ^ this._accessorsCreator.GetHashCode();
100 else
102 Assumes.NotNull(this._accessors);
103 Assumes.NotNull(this._accessors[0]);
104 return this.MemberType.GetHashCode() ^ this._accessors[0].GetHashCode();
108 public override bool Equals(object obj)
110 LazyMemberInfo that = (LazyMemberInfo)obj;
112 // Difefrent member types mean different members
113 if (this._memberType != that._memberType)
115 return false;
118 // if any of the lazy memebers create accessors in a delay-loaded fashion, we simply compare the creators
119 if ((this._accessorsCreator != null) || (that._accessorsCreator != null))
121 return object.Equals(this._accessorsCreator, that._accessorsCreator);
124 // we are dealing with explicitly passed accessors in both cases
125 Assumes.NotNull(this._accessors);
126 Assumes.NotNull(that._accessors);
127 return this._accessors.SequenceEqual(that._accessors);
130 public static bool operator ==(LazyMemberInfo left, LazyMemberInfo right)
132 return left.Equals(right);
135 public static bool operator !=(LazyMemberInfo left, LazyMemberInfo right)
137 return !left.Equals(right);
140 private static void EnsureSupportedMemberType(MemberTypes memberType, string argument)
142 MemberTypes supportedTypes = MemberTypes.TypeInfo | MemberTypes.NestedType | MemberTypes.Constructor | MemberTypes.Field | MemberTypes.Method | MemberTypes.Property | MemberTypes.Event;
143 Requires.IsInMembertypeSet(memberType, argument, supportedTypes);
146 private static bool AreAccessorsValid(MemberTypes memberType, MemberInfo[] accessors, out string errorMessage)
148 errorMessage = string.Empty;
149 if (accessors == null)
151 errorMessage = Strings.LazyMemberInfo_AccessorsNull;
152 return false;
155 if (accessors.All(accessor => accessor == null))
157 errorMessage = Strings.LazyMemberInfo_NoAccessors;
158 return false;
161 switch (memberType)
163 case MemberTypes.Property:
164 if (accessors.Length != 2)
166 errorMessage = Strings.LazyMemberInfo_InvalidPropertyAccessors_Cardinality;
167 return false;
170 if (accessors.Where(accessor => (accessor != null) && (accessor.MemberType != MemberTypes.Method)).Any())
172 errorMessage = Strings.LazyMemberinfo_InvalidPropertyAccessors_AccessorType;
173 return false;
176 break;
178 case MemberTypes.Event:
179 if (accessors.Length != 3)
181 errorMessage = Strings.LazyMemberInfo_InvalidEventAccessors_Cardinality;
182 return false;
185 if (accessors.Where(accessor => (accessor != null) && (accessor.MemberType != MemberTypes.Method)).Any())
187 errorMessage = Strings.LazyMemberinfo_InvalidPropertyAccessors_AccessorType;
188 return false;
191 break;
193 default:
194 if (
195 (accessors.Length != 1) ||
196 ((accessors.Length == 1) && (accessors[0].MemberType != memberType)))
198 errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.LazyMemberInfo_InvalidAccessorOnSimpleMember, memberType);
199 return false;
202 break;
204 return true;