标签: reflection

Activator.CreateInstance的目的是什么?

有人可以Activator.CreateInstance()详细解释目的吗?

.net c# reflection

110
推荐指数
6
解决办法
14万
查看次数

确定对象是否是基本类型

我有一个Object[]数组,我试图找到原始的数组.我试过用Class.isPrimitive(),但似乎我做错了什么:

int i = 3;
Object o = i;

System.out.println(o.getClass().getName() + ", " +
                   o.getClass().isPrimitive());
Run Code Online (Sandbox Code Playgroud)

打印java.lang.Integer, false.

有正确的方法或替代方案吗?

java reflection

109
推荐指数
9
解决办法
11万
查看次数

如何可靠地确定在设计时使用var声明的变量的类型?

我正在为emacs中的C#完成(intellisense)工具.

这个想法是,如果用户键入片段,然后通过特定的击键组合要求完成,则完成工具将使用.NET反射来确定可能的完成.

这样做需要知道正在完成的事物的类型.如果它是一个字符串,那么有一组已知的可能方法和属性; 如果它是一个Int32,它有一个单独的集,依此类推.

使用语义,emacs中提供的代码词法分析器/解析器包,我可以找到变量声明及其类型.鉴于此,可以直接使用反射来获取类型上的方法和属性,然后向用户显示选项列表.(好吧, emacs中做的不是那么简单,但是使用 emacs 中运行PowerShell进程的能力,它变得容易得多.我编写了一个自定义.NET程序集来进行反射,将其加载到powershell中,然后在内部运行elisp emacs可以通过comint向powershell发送命令并读取响应.因此,emacs可以快速获得反射结果.)

当代码var在声明正在完成的事物中使用时,问题就会到来.这意味着未明确指定类型,并且完成将不起作用.

当使用var关键字声明变量时,如何可靠地确定实际使用的类型?为了清楚起见,我不需要在运行时确定它.我想在"设计时"确定它.

到目前为止,我有这些想法:

  1. 编译并调用:
    • 提取声明语句,例如`var foo ="一个字符串值";`
    • 连接语句`foo.GetType();`
    • 将生成的C#片段动态编译为新的程序集
    • 将程序集加载到新的AppDomain中,运行framgment并获取返回类型.
    • 卸载并丢弃组件

    我知道怎么做这一切.但对于编辑器中的每个完成请求,它听起来非常重量级.

    我想我每次都不需要新的AppDomain.我可以为单个AppDomain重复使用多个临时程序集,并在多个完成请求中分摊设置和拆除它的成本.这更像是对基本理念的调整.

  2. 编译和检查IL

    只需将声明编译到模块中,然后检查IL,以确定编译器推断出的实际类型.这怎么可能?我会用什么来检查IL?

还有更好的想法吗?评论?建议?


编辑 - 进一步考虑这一点,编译和调用是不可接受的,因为调用可能有副作用.因此必须排除第一种选择.

此外,我认为我不能假设.NET 4.0的存在.


更新 - 上面没有提到的正确答案,但Eric Lippert温和地指出,是实现完全保真的类型推理系统.它是在设计时可靠地确定var类型的唯一方法.但是,这也不容易.因为我苦于没有幻想,我要试图建立这样的事情,我把选项2的快捷方式-提取相关声明代码,并编译它,然后检查所产生的IL.

这实际上适用于完成方案的公平子集.

例如,假设在下面的代码片段中,?是用户要求完成的位置.这有效:

var x = "hello there"; 
x.?
Run Code Online (Sandbox Code Playgroud)

完成意识到x是一个String,并提供适当的选项.它通过生成并编译以下源代码来实现:

namespace N1 {
  static class dmriiann5he { // randomly-generated class name
    static void M1 () {
       var x = "hello there"; 
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

......然后用简单的反射检查IL.

这也有效:

var x …
Run Code Online (Sandbox Code Playgroud)

c# reflection type-inference appdomain

109
推荐指数
3
解决办法
3万
查看次数

如何以递归方式将所有引用加载到AppDomain的程序集?

我想加载到一个新的AppDomain一些具有复杂引用树的程序集(MyDll.dll - > Microsoft.Office.Interop.Excel.dll - > Microsoft.Vbe.Interop.dll - > Office.dll - > stdole.dll)

据我所知,当加载程序集时AppDomain,它的引用不会自动加载,我必须手动加载它们.所以当我这样做时:

string dir = @"SomePath"; // different from AppDomain.CurrentDomain.BaseDirectory
string path = System.IO.Path.Combine(dir, "MyDll.dll");

AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
setup.ApplicationBase = dir;
AppDomain domain = AppDomain.CreateDomain("SomeAppDomain", null, setup);

domain.Load(AssemblyName.GetAssemblyName(path));
Run Code Online (Sandbox Code Playgroud)

得到了FileNotFoundException:

无法加载文件或程序集"MyDll,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null"或其依赖项之一.该系统找不到指定的文件.

我认为关键部分是其依赖性之一.

好的,我之前做过 domain.Load(AssemblyName.GetAssemblyName(path));

foreach (AssemblyName refAsmName in Assembly.ReflectionOnlyLoadFrom(path).GetReferencedAssemblies())
{
    domain.Load(refAsmName);
}
Run Code Online (Sandbox Code Playgroud)

FileNotFoundException又一次,在另一个(参考)集会上.

如何递归加载所有引用?

在加载根程序集之前是否必须创建引用树?如何在不加载程序集的情况下获取程序集的引用?

.net c# reflection assemblies appdomain

108
推荐指数
7
解决办法
12万
查看次数

通过Java中的反射访问私有继承的字段

我找到了一种方法来获取继承成员通过 class.getDeclaredFields(); 和访问私人成员,class.getFields() 但我正在寻找私人继承的字段.我怎样才能实现这一目标?

java reflection inheritance private-members

107
推荐指数
7
解决办法
9万
查看次数

如何使用Reflection获取静态属性

所以这看起来非常基本,但我无法让它发挥作用.我有一个Object,我使用反射来获取它的公共属性.其中一个属性是静态的,我没有运气.

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo
    Return obj.GetType.GetProperty(propName)

End Function
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于Public Instance属性,到目前为止我只需要它.据说我可以使用BindingFlags来请求其他类型的属性(私有,静态),但我似乎找不到合适的组合.

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo
    Return obj.GetType.GetProperty(propName, Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public)

End Function
Run Code Online (Sandbox Code Playgroud)

但是,请求任何静态成员返回任何内容..NET反射器可以很好地看到静态属性,所以很明显我在这里遗漏了一些东西.

.net reflection static

104
推荐指数
5
解决办法
10万
查看次数

使用PropertyInfo查找属性类型

我想动态解析一个对象树来做一些自定义验证.验证并不重要,但我想更好地理解PropertyInfo类.

我会做这样的事情,

public bool ValidateData(object data)
{
    foreach (PropertyInfo propertyInfo in data.GetType().GetProperties())
    {
        if (the property is a string)
        {
            string value = propertyInfo.GetValue(data, null);

            if value is not OK
            {
                return false;
            }
        }
    }            

    return true;
}
Run Code Online (Sandbox Code Playgroud)

我现在关心的唯一部分是'如果属性是字符串'.如何从PropertyInfo对象中找出它的类型.

我将不得不处理基本的东西,如字符串,整数,双打.但我也必须处理对象,如果是这样,我将需要在对象树中进一步向下遍历这些对象以验证其中的基本数据,它们也将具有字符串等.

谢谢.

.net c# reflection

103
推荐指数
1
解决办法
11万
查看次数

如何使用反射检查方法是否是静态的?

我想在运行时发现一个类的静态方法,我该怎么做?或者,如何区分静态和非静态方法.

java reflection

102
推荐指数
3
解决办法
5万
查看次数

查找已定义类的PHP文件(在运行时)

PHP中是否有任何反射/内省/魔术可以让你找到定义特定类(或函数)的PHP文件?

换句话说,我有一个PHP类的名称,或一个实例化的对象.我想将此传递给某些东西(函数,Reflection类等),它将返回定义类的文件系统路径.

/path/to/class/definition.php
Run Code Online (Sandbox Code Playgroud)

我意识到我可以使用(get_included_files())获取到目前为止已包含的所有文件的列表,然后手动解析它们,但这是一次尝试的大量文件系统访问.

我也意识到我可以在我们的__autoload机制中编写一些额外的代码来缓存这些信息.但是,在我想到的情况下,修改现有的__autoload是不受限制的.

听说可以做到这一点的扩展会很有趣,但我最终会喜欢可以在"库存"安装上运行的东西.

php reflection class

102
推荐指数
3
解决办法
5万
查看次数

用反射调用静态方法

我在命名空间中有几个静态类,mySolution.Macros例如

static class Indent{    
     public static void Run(){
         // implementation
     }
     // other helper methods
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何在反射的帮助下调用这些方法?

如果方法不是静态的那么我可以做类似的事情:

var macroClasses = Assembly.GetExecutingAssembly().GetTypes().Where( x => x.Namespace.ToUpper().Contains("MACRO") );

foreach (var tempClass in macroClasses)
{
   var curInsance = Activator.CreateInstance(tempClass);
   // I know have an instance of a macro and will be able to run it

   // using reflection I will be able to run the method as:
   curInsance.GetType().GetMethod("Run").Invoke(curInsance, null);
}
Run Code Online (Sandbox Code Playgroud)

我想让我的课程保持静态.我怎么能用静态方法做类似的事情?

简而言之,我想从命名空间mySolution.Macros中的所有静态类调用所有Run方法.

c# reflection dynamic

102
推荐指数
3
解决办法
9万
查看次数