// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Microsoft.Internal;
namespace System.ComponentModel.Composition.Primitives{
[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public class ExportedDelegate
{
private object _instance;
private MethodInfo _method;
protected ExportedDelegate() { }
public ExportedDelegate(object instance, MethodInfo method)
{
Requires.NotNull(method, "method");
this._instance = instance;
this._method = method;
}
public virtual Delegate CreateDelegate(Type delegateType)
{
Requires.NotNull(delegateType, "delegateType");
if (delegateType == typeof(Delegate) || delegateType == typeof(MulticastDelegate))
{
Type funcOrAction = ConvertMethodInfoToFuncOrActionType(this._method);
if (funcOrAction != null)
{
delegateType = funcOrAction;
}
else
{
return null;
}
}
return Delegate.CreateDelegate(delegateType, this._instance, this._method, false);
}
private static Type[] _funcTypes =
{
typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>)
#if CLR40 && !SILVERLIGHT
, typeof(Func<,,,,,>), typeof(Func<,,,,,,>), typeof(Func<,,,,,,,>), typeof(Func<,,,,,,,,>)
#endif
};
private static Type[] _actionTypes =
{
typeof(Action), typeof(Action<>), typeof(Action<,>), typeof(Action<,,>), typeof(Action<,,,>)
#if CLR40 && !SILVERLIGHT
, typeof(Action<,,,,>), typeof(Action<,,,,,>), typeof(Action<,,,,,,>), typeof(Action<,,,,,,,>)
#endif
};
private static Type ConvertMethodInfoToFuncOrActionType(MethodInfo method)
{
ParameterInfo[] parameters = method.GetParameters();
bool isVoid = method.ReturnType == typeof(void);
Type[] typeArray = isVoid ? _actionTypes : _funcTypes;
if (parameters.Length >= typeArray.Length)
{
return null;
}
Type[] genericArgTypes = new Type[parameters.Length + (isVoid ? 0 : 1)];
for (int i = 0; i < parameters.Length; i++)
{
genericArgTypes[i] = parameters[i].ParameterType;
}
if (!isVoid)
{
genericArgTypes[parameters.Length] = method.ReturnType;
}
Type delegateType = typeArray[parameters.Length].IsGenericType ?
typeArray[parameters.Length].MakeGenericType(genericArgTypes) :
typeArray[parameters.Length];
return delegateType;
}
}
}
|