Tag: reflection

RuntimeReflectionExtensions.GetRuntimeMethod无法按预期工作

有没有人知道为什么调用GetRuntimeMethod为以下情况返回null? _toListMethod = typeof(Enumerable).GetRuntimeMethod(“ToList”, new Type[] { typeof(IEnumerable) }); 它应该像它一样工作: _castMethod = typeof(Enumerable).GetRuntimeMethod(“Cast”, new Type[] { typeof(IEnumerable) }); 我尝试通过运行以下代码来调试它: var bah = typeof (Enumerable).GetRuntimeMethods().Where(m => m.Name.Contains(“ToList”)); var derp = bah.First().GetParameters(); 令我惊讶的是,第一行返回一个集合,其中包含我想要获取的MethodInfo,第二行确认预期的参数类型是IEnumerable 。 两个方法签名,Cast和ToList是相似的,我看不出为什么获取ToList的MethodInfo会失败的任何原因。 此代码在可移植类库上运行,TargetFrameworkProfile设置为Profile78。 谢谢! 更新:在我有一个很好的解决方案之前,有一个丑陋的解决方法对我有用: _toListMethod = typeof(Enumerable).GetRuntimeMethods().First(m => m.Name.Contains(“ToList”));

Activator.CreateInstance:无法从程序集加载类型

我正在尝试在我的项目中创建一个在插件.dll中实现的类的实例来进行类型发现。 我收到了这个例外: 无法从程序集’SquidReports.DataCollector.Plugin.BES,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null’加载类型’Action’。 这是我正在使用的确切方法签名: https : //msdn.microsoft.com/en-us/library/d133hta4(v = vs.110).aspx 换句话说,我试图根据程序集名称和类名生成对象,如下所示: object modelObject = Activator.CreateInstance((string)modelInfo.AssemblyName, (string)modelInfo.ModelName); 这里要注意的一个重要部分是我使用程序集的“短”名称而不是“完整”名称(包括Version,Culture和PublicToken)。 但是,MSDN明确指出: ‘assemblyName’可以是以下任一种:程序集的简单名称,没有其路径或文件扩展名。 例如,您可以为路径和名称为。\ bin \ TypeExtensions.dll的程序集指定TypeExtensions。 已签名程序集的全名,包括其简单名称,版本,区域性和公钥标记; 例如,“TypeExtensions,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = 181869f2f7435b51”。 具体来说,我正在尝试创建一个在程序集’SquidReports.DataCollector.Plugin.BES’中定义的类’Action’的实例。 我明确地将此程序集引用为完全相同* .cs文件顶部的using指令,我正在尝试创建该实例。 我从之前的问题/答案中尝试了以下建议: 清理你的解决方案,重建并再试一次这似乎适用于一些ASP.NET项目,但这是一个简单的旧控制台应用程序。 检查配置文件中引用的程序集再次,这是一个简单的控制台应用程序,只在同一解决方案的不同项目中使用GAC和库 1.确保程序集位于正确的工作目录中: 我们到了… 2.确保程序集是磁盘上的相同版本 对… 3.最终的建议是使用fuslogvw.exe。 我没有使用该工具的经验,但有一件事我觉得很奇怪。 在运行调试会话时,我的程序集的长命名和短命名版本都出现了: 我看了看两个日志。 这个命名短的版本确实会产生一些警告: ===预绑定状态信息=== LOG:DisplayName = SquidReports.DataCollector.Plugin.BES […]

Lambda表达式<T,Func >和MethodInfo

在将项目从VS2010迁移到VS2012时,我遇到了以下问题。 该项目使用了很多reflection,为了从接口获取MethodInfo,放置了以下代码: Expression<Func<ITest, Func>> expression = scv => scv.Get; UnaryExpression unaryExpression = expression.Body as UnaryExpression; MethodCallExpression methodCallExpression = unaryExpression.Operand as MethodCallExpression; ConstantExpression constantExpression = methodCallExpression.Arguments[2] as ConstantExpression; MethodInfo myMethod = constantExpression.Value as MethodInfo; 使用VS2010编译时效果很好,但是如果使用针对.Net 4.0的VS2012编译代码,则methodCallExpression.Arguments.Count()为2。 反编译后,我注意到编译器为同一个表达式生成了不同的代码。 这是一个设计问题,因为设计不应该像methodCallExpression.Arguments [2]中的数字2那样继续传递“幻数”。 我尝试使用以下方法找到解决方案: MethodCallExpression outermostExpression = expression .Body as MethodCallExpression; MethodInfo myMethod = outermostExpression.Method; 但是outermostExpression为null。 最后,我让它改变了表达式如下: Expression<Func> expression = […]

如何使用reflection或替代方法以编程方式创建函数调用?

我有点像reflection的新手。 我希望能做到我喜欢的事情。 我一直在通过ProjectEuler学习语言,我有一个名为Problem的基类。 每个PE问题都是一个单独的类,即Problem16。 要运行我的计算,我使用以下代码: using System; using Euler.Problems; using Euler.Library; namespace Euler { static class Program { [STAThread] static void Main() { Problem prob = new Problem27(); } } } 我现在已经完成了50个问题,我想创建一个循环来运行它们。 我的基类问题有一个方法,它在文本文件中附加问题编号,答案和在每个类的默认构造函数中调用的执行时间。 我可以手动更改所有50的函数调用,但是当我继续完成问题时,这将最终成为很多工作。 我宁愿以编程方式来做。 我希望这个伪代码成为现实: for (int i = 1; i <= 50; i++) { string statement = "Problem prob = new Problem" + […]

如何从Action委托创建MethodInfo

我正在尝试开发一个NUnit插件,它从包含Action委托列表的对象动态地将测试方法添加到套件中。 问题在于NUnit似乎非常倾向于反思以完成工作。 因此,看起来没有简单的方法将Action直接添加到套件中。 相反,我必须添加MethodInfo对象。 这通常有效,但Action代理是匿名的,所以我必须构建完成此任务的类型和方法。 我需要找到一种更简单的方法来做到这一点,而不需要使用Emit 。 有谁知道如何从Action代理轻松创建MethodInfo实例?

在C#中使用“类型”对象键入转换对象

到目前为止,这个对我来说有点棘手。 我想知道是否可以使用System.Type对象键入强制转换对象。 我在下面说明了我的意思: public interface IDataAdapter { object Transform(object input); Type GetOutputType(); } public class SomeRandomAdapter : IDataAdapter { public object Transform(object input) { string output; // Do some stuff to transform input to output… return output; } public Type GetOutputType() { return typeof(string); } } // Later when using the above methods I would […]

如何使用强类型reflection为generics类的方法找到MethodInfo?

我想从具有仅在运行时知道的类型参数的generics类中获取方法的MethodInfo 。 以下是从非generics类获取generics方法的MethodInfo的方法: class MyClass { public void MyMethod (T arg) { } } static MethodInfo Resolve (Type type) { Expression<Action> lambda = (c, a) => c.MyMethod (a); MethodCallExpression call = lambda.Body as MethodCallExpression; return call .Method // Get MethodInfo for MyClass.MyMethod .GetGenericMethodDefinition () // Get MethodInfo for MyClass.MyMethod .MakeGenericMethod (type); // Get MethodInfo for […]

确定MethodInfo实例是否是属性访问器

我正在使用Castle DynamicProxy编写装饰代理。 我需要代理的拦截器来拦截属性写入(而不是读取)所以我正在检查方法的名称: public void Intercept(IInvocation invocation) { if (invocation.Method.Name.StartsWith(“set_”) { // … } invocation.Proceed(); } 现在这个工作正常但我不喜欢我的代理知道如何实现属性的事实:我想用类似于以下内容的方法替换方法名称检查: if (invocation.Method.IsPropertySetAccessor) 不幸的是,我的Google-fu让我失望了。 有任何想法吗?

超越属性和reflection的奇怪效应

我在.NET / Reflection中遇到了一个奇怪的行为,无法找到任何解决方案/解释: class A { public virtual string TestString { get; set; } } class B : A { public override string TestString { get { return “x”; } } } 由于属性只是函数对( get_PropName() , set_PropName() get_PropName() , set_PropName()只覆盖“get”部分应该保留“set”部分,就像它在基类中一样。 这就是如果您尝试实例化B类并为TestString赋值,它会使用A类的实现。 但是如果我在reflection中查看B类的实例化对象会发生什么呢? PropertyInfo propInfo = b.GetType().GetProperty(“TestString”); propInfo.CanRead —> true propInfo.CanWrite —> false(!) 如果我尝试从reflection中调用setter: propInfo.SetValue(“test”, b, null); […]

通过Bytes加载程序集会丢失该位置

我想通过以下方式加载程序集 var loadedAssembly = Assembly.Load(File.ContentsAsBytes); File.ContentAsBytes通过以下方式将dll作为byte[]返回 System.IO.File.ReadAllBytes(“dll location”); 问题是加载的程序集( loadedAssembly )失去了它的物理位置 loadedAssembly.CodeBase – 设置为正在加载它的程序集(这是不正确的) loadedAssembly.Location – 为空 有没有办法从byte[]加载并获得类似的结果到Assembly.LoadFile因为我需要结果与AppDomain.CurrentDomain.AssemblyResolve