1
// -----------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // -----------------------------------------------------------------------
5 using System
.Diagnostics
.CodeAnalysis
;
6 using System
.Globalization
;
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) }
;
35 case MemberTypes
.Event
:
36 EventInfo event_
= (EventInfo
)member
;
37 this._accessors
= new MemberInfo
[] { event_.GetRaiseMethod(true), event_.GetAddMethod(true), event_.GetRemoveMethod(true) }
;
40 this._accessors
= new MemberInfo
[] { member }
;
45 public LazyMemberInfo(MemberTypes memberType
, params MemberInfo
[] accessors
)
47 EnsureSupportedMemberType(memberType
, "memberType");
48 Requires
.NotNull(accessors
, "accessors");
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();
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();
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
)
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
;
155 if (accessors
.All(accessor
=> accessor
== null))
157 errorMessage
= Strings
.LazyMemberInfo_NoAccessors
;
163 case MemberTypes
.Property
:
164 if (accessors
.Length
!= 2)
166 errorMessage
= Strings
.LazyMemberInfo_InvalidPropertyAccessors_Cardinality
;
170 if (accessors
.Where(accessor
=> (accessor
!= null) && (accessor
.MemberType
!= MemberTypes
.Method
)).Any())
172 errorMessage
= Strings
.LazyMemberinfo_InvalidPropertyAccessors_AccessorType
;
178 case MemberTypes
.Event
:
179 if (accessors
.Length
!= 3)
181 errorMessage
= Strings
.LazyMemberInfo_InvalidEventAccessors_Cardinality
;
185 if (accessors
.Where(accessor
=> (accessor
!= null) && (accessor
.MemberType
!= MemberTypes
.Method
)).Any())
187 errorMessage
= Strings
.LazyMemberinfo_InvalidPropertyAccessors_AccessorType
;
195 (accessors
.Length
!= 1) ||
196 ((accessors
.Length
== 1) && (accessors
[0].MemberType
!= memberType
)))
198 errorMessage
= string.Format(CultureInfo
.CurrentCulture
, Strings
.LazyMemberInfo_InvalidAccessorOnSimpleMember
, memberType
);