3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // <OWNER>Microsoft</OWNER>
10 using System
.Security
;
11 using System
.Reflection
;
12 using System
.Diagnostics
.Contracts
;
13 using System
.Runtime
.InteropServices
;
14 using System
.Runtime
.CompilerServices
;
15 using System
.Runtime
.Serialization
;
16 using System
.StubHelpers
;
17 using System
.Globalization
;
19 namespace System
.Runtime
.InteropServices
.WindowsRuntime
22 // ICustomProperty implementation - basically a wrapper of PropertyInfo
24 internal sealed class CustomPropertyImpl
: ICustomProperty
26 private PropertyInfo m_property
;
31 public CustomPropertyImpl(PropertyInfo propertyInfo
)
33 if (propertyInfo
== null)
34 throw new ArgumentNullException("propertyInfo");
36 m_property
= propertyInfo
;
40 // ICustomProperty interface implementation
47 return m_property
.Name
;
55 // Return false if the getter is not public
56 return m_property
.GetGetMethod() != null;
64 // Return false if the setter is not public
65 return m_property
.GetSetMethod() != null;
69 public object GetValue(object target
)
71 return InvokeInternal(target
, null, true);
74 // Unlike normal .Net, Jupiter properties can have at most one indexer parameter. A null
75 // indexValue here means that the property has an indexer argument and its value is null.
76 public object GetValue(object target
, object indexValue
)
78 return InvokeInternal(target
, new object[] { indexValue }
, true);
81 public void SetValue(object target
, object value)
83 InvokeInternal(target
, new object[] { value }
, false);
86 // Unlike normal .Net, Jupiter properties can have at most one indexer parameter. A null
87 // indexValue here means that the property has an indexer argument and its value is null.
88 public void SetValue(object target
, object value, object indexValue
)
90 InvokeInternal(target
, new object[] { indexValue, value }
, false);
93 [SecuritySafeCritical
]
94 private object InvokeInternal(object target
, object[] args
, bool getValue
)
96 // Forward to the right object if we are dealing with a proxy
97 IGetProxyTarget proxy
= target
as IGetProxyTarget
;
100 target
= proxy
.GetTarget();
103 // You can get PropertyInfo for properties with a private getter/public setter (or vice versa)
104 // even if you pass BindingFlags.Public only. And in this case, passing binding flags to
105 // GetValue/SetValue won't work as the default binder ignores those values
106 // Use GetGetMethod/GetSetMethod instead
108 // We get non-public accessors just so that we can throw the correct exception.
109 MethodInfo accessor
= getValue
? m_property
.GetGetMethod(true) : m_property
.GetSetMethod(true);
111 if (accessor
== null)
112 throw new ArgumentException(System
.Environment
.GetResourceString(getValue
? "Arg_GetMethNotFnd" : "Arg_SetMethNotFnd"));
114 if (!accessor
.IsPublic
)
115 throw new MethodAccessException(
117 CultureInfo
.CurrentCulture
,
118 Environment
.GetResourceString("Arg_MethodAccessException_WithMethodName"),
120 accessor
.DeclaringType
.FullName
));
122 RuntimeMethodInfo rtMethod
= accessor
as RuntimeMethodInfo
;
123 if (rtMethod
== null)
124 throw new ArgumentException(Environment
.GetResourceString("Argument_MustBeRuntimeMethodInfo"));
126 // We can safely skip access check because this is only used in full trust scenarios.
127 // And we have already verified that the property accessor is public.
128 Contract
.Assert(AppDomain
.CurrentDomain
.PermissionSet
.IsUnrestricted());
129 return rtMethod
.UnsafeInvoke(target
, BindingFlags
.Default
, null, args
, null);
136 return m_property
.PropertyType
;