Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / mscorlib / system / runtime / interopservices / windowsruntime / custompropertyimpl.cs
blobbf762dbefe9d9750d83abb26f06e575153cb7996
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 //
7 // <OWNER>Microsoft</OWNER>
9 using System;
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;
29 // Constructor
31 public CustomPropertyImpl(PropertyInfo propertyInfo)
33 if (propertyInfo == null)
34 throw new ArgumentNullException("propertyInfo");
36 m_property = propertyInfo;
40 // ICustomProperty interface implementation
43 public string Name
45 get
47 return m_property.Name;
51 public bool CanRead
53 get
55 // Return false if the getter is not public
56 return m_property.GetGetMethod() != null;
60 public bool CanWrite
62 get
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;
98 if (proxy != null)
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(
116 String.Format(
117 CultureInfo.CurrentCulture,
118 Environment.GetResourceString("Arg_MethodAccessException_WithMethodName"),
119 accessor.ToString(),
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);
132 public Type Type
136 return m_property.PropertyType;