我意识到,一般来说,使用反射会产生性能影响.(事实上,我自己并不是反思的粉丝;这是一个纯粹的学术问题.)
假设存在一些看起来像这样的类:
public class MyClass {
public string GetName() {
return "My Name";
}
}
Run Code Online (Sandbox Code Playgroud)
跟我来这儿.我知道如果我有一个MyClass
被叫的实例x
,我可以打电话x.GetName()
.此外,我可以设置一个Func<string>
变量x.GetName
.
现在这是我的问题.假设我不知道上面的类叫做MyClass
; 我有一些对象,x
但我不知道它是什么.我可以GetName
通过这样做来检查该对象是否有方法:
MethodInfo getName = x.GetType().GetMethod("GetName");
Run Code Online (Sandbox Code Playgroud)
假设getName
不为空.然后,我不能进一步检查getName.ReturnType == typeof(string)
和getName.GetParameters().Length == 0
,在这一点上,我岂不是很肯定的是,在我所代表的方法,getName
对象可以肯定被转换为一个Func<string>
,不知何故?
我意识到有一个MethodInfo.Invoke
,我也意识到我总能创造一个Func<string>
像:
Func<string> getNameFunc = () => getName.Invoke(x, null);
Run Code Online (Sandbox Code Playgroud)
我想我要问的是,是否有任何方法可以从一个MethodInfo
对象转到它所代表的实际方法,从而在该过程中产生反射的性能成本,但 …
使用反射来获取MethodInfo,我想测试返回的类型是否为typeof System.Void.
测试它是否是System.Int32正常工作
myMethodInfo.ReturnType == typeof(System.Int32)
Run Code Online (Sandbox Code Playgroud)
但
myMethodInfo.ReturnType == typeof(System.Void)
Run Code Online (Sandbox Code Playgroud)
不编译?目前我正在测试名称的字符串表示是否为"System.Void",这看起来非常错误.
我需要一个方法,该方法接受一个MethodInfo
表示具有任意签名的非泛型静态方法的实例,并返回绑定到该方法的委托,该委托稍后可以使用Delegate.DynamicInvoke
方法调用.我的第一次天真尝试看起来像这样:
using System;
using System.Reflection;
class Program
{
static void Main()
{
var method = CreateDelegate(typeof (Console).GetMethod("WriteLine", new[] {typeof (string)}));
method.DynamicInvoke("Hello world");
}
static Delegate CreateDelegate(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
if (!method.IsStatic)
{
throw new ArgumentNullException("method", "The provided method is not static.");
}
if (method.ContainsGenericParameters)
{
throw new ArgumentException("The provided method contains unassigned generic type parameters.");
}
return method.CreateDelegate(typeof(Delegate)); // This does not work: System.ArgumentException: Type must derive from …
Run Code Online (Sandbox Code Playgroud) 如何将参数作为参考传递MethodInfo.Invoke
?
这是我想要调用的方法:
private static bool test(string str, out byte[] byt)
Run Code Online (Sandbox Code Playgroud)
我尝试了这个,但我失败了:
byte[] rawAsm = new byte[]{};
MethodInfo _lf = asm.GetTypes()[0].GetMethod("test", BindingFlags.Static | BindingFlags.NonPublic);
bool b = (bool)_lf.Invoke(null, new object[]
{
"test",
rawAsm
});
Run Code Online (Sandbox Code Playgroud)
返回的字节为空.
我想从MethodInfo对象获取一个动作委托.这可能吗?
谢谢.
谷歌搜索和登陆后,阅读了另一个问题
如果您在编译时不知道参数的数量或类型,是否可以从MethodInfo构建正确的委托?
更多关于此:如果不使用Reflection.Emit或类型构建器,这可以优雅地完成吗?
这对我来说有点令人失望,因为Delegate.CreateDelegate要求我指定正确的Delegate类型作为第一个参数,否则它会抛出异常或调用不正确的方法.
我正在建造一些忍者齿轮,这会有很大的帮助......谢谢!
这是一个通用的解决方案:
/// <summary>
/// Builds a Delegate instance from the supplied MethodInfo object and a target to invoke against.
/// </summary>
public static Delegate ToDelegate(MethodInfo mi, object target)
{
if (mi == null) throw new ArgumentNullException("mi");
Type delegateType;
var typeArgs = mi.GetParameters()
.Select(p => p.ParameterType)
.ToList();
// builds a delegate type
if (mi.ReturnType == typeof(void)) {
delegateType = Expression.GetActionType(typeArgs.ToArray());
} else {
typeArgs.Add(mi.ReturnType);
delegateType = Expression.GetFuncType(typeArgs.ToArray());
}
// creates a binded …
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试从中创建委托MethodInfo
.我的总体目标是查看类中的方法并为标记有特定属性的方法创建委托.我正在尝试使用,CreateDelegate
但我收到以下错误.
无法绑定到目标方法,因为其签名或安全透明性与委托类型的签名或安全透明性不兼容.
这是我的代码
public class TestClass
{
public delegate void TestDelagate(string test);
private List<TestDelagate> delagates = new List<TestDelagate>();
public TestClass()
{
foreach (MethodInfo method in this.GetType().GetMethods())
{
if (TestAttribute.IsTest(method))
{
TestDelegate newDelegate = (TestDelagate)Delegate.CreateDelegate(typeof(TestDelagate), method);
delegates.Add(newDelegate);
}
}
}
[Test]
public void TestFunction(string test)
{
}
}
public class TestAttribute : Attribute
{
public static bool IsTest(MemberInfo member)
{
bool isTestAttribute = false;
foreach (object attribute in member.GetCustomAttributes(true))
{
if (attribute is TestAttribute)
isTestAttribute = true; …
Run Code Online (Sandbox Code Playgroud) 我有MethodInfo
一个的接口方法和Type
一个的类实现了接口.我想找到MethodInfo
实现接口方法的类方法.
简单method.GetBaseDefinition()
不适用于接口方法.按名称查找也不起作用,因为当显式实现接口方法时,它可以有任何名称(是的,不是在C#中).
那么正确的做法是什么,涵盖所有可能性?
我在运行时使用Reflection进行一些类型分析.如果我有一个MethodInfo实例,我怎么能弄清楚这是一个"真正的"方法还是一个属性的getter/setter方法?如果它是一个属性,我怎样才能找到它的托管PropertyInfo?
更新:我已经在Microsoft Connect上提交了错误报告:https://connect.microsoft.com/VisualStudio/feedback/details/568271/debugger-halting-on-exception-thrown-inside-methodinfo-invoke#details
如果您可以在您的机器上重现此问题,请提供错误,以便修复它!
好的,我已经做了一些测试,我把问题简化为非常简单的事情:
一世.在抛出异常的新类中创建方法:
public class Class1 {
public void CallMe() {
string blah = null;
blah.ToLower();
}
}
Run Code Online (Sandbox Code Playgroud)
II.创建一个MethodInfo,在其他地方指向此方法:
Type class1 = typeof( Class1 );
Class1 obj = new Class1();
MethodInfo method = class1.GetMethod( "CallMe" );
Run Code Online (Sandbox Code Playgroud)
III.在try/catch块中包含对Invoke()的调用:
try {
method.Invoke( obj, null ); // exception is not being caught!
} catch {
}
Run Code Online (Sandbox Code Playgroud)
IV.没有调试器运行程序(工作正常).
v.现在使用调试器运行程序.发生异常时,调试器将暂停程序,即使它包含在试图忽略它的catch处理程序中.(即使你在catch块中放置了一个断点,它会在它到达之前停止!)
实际上,在没有调试器的情况下运行它时会发生异常.在一个简单的测试项目中,它在某个其他级别被忽略,但如果您的应用程序有任何类型的全局异常处理,它也会在那里被触发. [看评论]
这让我很头疼,因为它一直在触发我的应用程序的崩溃处理程序,更不用说尝试调试的痛苦了.
methodinfo ×10
reflection ×8
.net ×6
c# ×6
delegates ×3
action ×1
attributes ×1
clr ×1
func ×1
invoke ×1
performance ×1
propertyinfo ×1