1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
#if HAS_WINRT
using System.Runtime.InteropServices.WindowsRuntime;
#endif
namespace System.Reactive
{
static class ReflectionUtils
{
public static TDelegate CreateDelegate<TDelegate>(object o, MethodInfo method)
{
#if CRIPPLED_REFLECTION
return (TDelegate)(object)method.CreateDelegate(typeof(TDelegate), o);
#else
return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), o, method);
#endif
}
public static Delegate CreateDelegate(Type delegateType, object o, MethodInfo method)
{
#if CRIPPLED_REFLECTION
return method.CreateDelegate(delegateType, o);
#else
return Delegate.CreateDelegate(delegateType, o, method);
#endif
}
public static void GetEventMethods<TSender, TEventArgs>(Type targetType, object target, string eventName, out MethodInfo addMethod, out MethodInfo removeMethod, out Type delegateType, out bool isWinRT)
#if !NO_EVENTARGS_CONSTRAINT
where TEventArgs : EventArgs
#endif
{
var e = default(EventInfo);
if (target == null)
{
e = targetType.GetEventEx(eventName, true);
if (e == null)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.COULD_NOT_FIND_STATIC_EVENT, eventName, targetType.FullName));
}
else
{
e = targetType.GetEventEx(eventName, false);
if (e == null)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.COULD_NOT_FIND_INSTANCE_EVENT, eventName, targetType.FullName));
}
addMethod = e.GetAddMethod();
removeMethod = e.GetRemoveMethod();
if (addMethod == null)
throw new InvalidOperationException(Strings_Linq.EVENT_MISSING_ADD_METHOD);
if (removeMethod == null)
throw new InvalidOperationException(Strings_Linq.EVENT_MISSING_REMOVE_METHOD);
var psa = addMethod.GetParameters();
if (psa.Length != 1)
throw new InvalidOperationException(Strings_Linq.EVENT_ADD_METHOD_SHOULD_TAKE_ONE_PARAMETER);
var psr = removeMethod.GetParameters();
if (psr.Length != 1)
throw new InvalidOperationException(Strings_Linq.EVENT_REMOVE_METHOD_SHOULD_TAKE_ONE_PARAMETER);
isWinRT = false;
#if HAS_WINRT
if (addMethod.ReturnType == typeof(EventRegistrationToken))
{
isWinRT = true;
var pet = psr[0];
if (pet.ParameterType != typeof(EventRegistrationToken))
throw new InvalidOperationException(Strings_Linq.EVENT_WINRT_REMOVE_METHOD_SHOULD_TAKE_ERT);
}
#endif
delegateType = psa[0].ParameterType;
var invokeMethod = delegateType.GetMethod("Invoke");
var parameters = invokeMethod.GetParameters();
if (parameters.Length != 2)
throw new InvalidOperationException(Strings_Linq.EVENT_PATTERN_REQUIRES_TWO_PARAMETERS);
if (!typeof(TSender).IsAssignableFrom(parameters[0].ParameterType))
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE, typeof(TSender).FullName));
if (!typeof(TEventArgs).IsAssignableFrom(parameters[1].ParameterType))
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE, typeof(TEventArgs).FullName));
if (invokeMethod.ReturnType != typeof(void))
throw new InvalidOperationException(Strings_Linq.EVENT_MUST_RETURN_VOID);
}
public static EventInfo GetEventEx(this Type type, string name, bool isStatic)
{
#if CRIPPLED_REFLECTION
// TODO: replace in the future by System.Reflection.RuntimeExtensions extension methods
var q = new Queue<TypeInfo>();
q.Enqueue(type.GetTypeInfo());
while (q.Count > 0)
{
var t = q.Dequeue();
var e = t.GetDeclaredEvent(name);
if (e != null)
return e;
foreach (var i in t.ImplementedInterfaces)
q.Enqueue(i.GetTypeInfo());
if (t.BaseType != null)
q.Enqueue(t.BaseType.GetTypeInfo());
}
return null;
#else
return type.GetEvent(name, isStatic ? BindingFlags.Public | BindingFlags.Static : BindingFlags.Public | BindingFlags.Instance);
#endif
}
#if CRIPPLED_REFLECTION
public static MethodInfo GetMethod(this Type type, string name)
{
return type.GetTypeInfo().GetDeclaredMethod(name);
}
public static MethodInfo GetAddMethod(this EventInfo eventInfo)
{
return eventInfo.AddMethod;
}
public static MethodInfo GetRemoveMethod(this EventInfo eventInfo)
{
return eventInfo.RemoveMethod;
}
public static bool IsAssignableFrom(this Type type1, Type type2)
{
return type1.GetTypeInfo().IsAssignableFrom(type2.GetTypeInfo());
}
#endif
}
}
|