有人可以Activator.CreateInstance()详细解释目的吗?
我有一个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.
有正确的方法或替代方案吗?
我正在为emacs中的C#完成(intellisense)工具.
这个想法是,如果用户键入片段,然后通过特定的击键组合要求完成,则完成工具将使用.NET反射来确定可能的完成.
这样做需要知道正在完成的事物的类型.如果它是一个字符串,那么有一组已知的可能方法和属性; 如果它是一个Int32,它有一个单独的集,依此类推.
使用语义,emacs中提供的代码词法分析器/解析器包,我可以找到变量声明及其类型.鉴于此,可以直接使用反射来获取类型上的方法和属性,然后向用户显示选项列表.(好吧,在 emacs中做的不是那么简单,但是使用在 emacs 中运行PowerShell进程的能力,它变得容易得多.我编写了一个自定义.NET程序集来进行反射,将其加载到powershell中,然后在内部运行elisp emacs可以通过comint向powershell发送命令并读取响应.因此,emacs可以快速获得反射结果.)
当代码var在声明正在完成的事物中使用时,问题就会到来.这意味着未明确指定类型,并且完成将不起作用.
当使用var关键字声明变量时,如何可靠地确定实际使用的类型?为了清楚起见,我不需要在运行时确定它.我想在"设计时"确定它.
到目前为止,我有这些想法:
我知道怎么做这一切.但对于编辑器中的每个完成请求,它听起来非常重量级.
我想我每次都不需要新的AppDomain.我可以为单个AppDomain重复使用多个临时程序集,并在多个完成请求中分摊设置和拆除它的成本.这更像是对基本理念的调整.
只需将声明编译到模块中,然后检查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) 我想加载到一个新的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又一次,在另一个(参考)集会上.
如何递归加载所有引用?
在加载根程序集之前是否必须创建引用树?如何在不加载程序集的情况下获取程序集的引用?
我找到了一种方法来获取继承成员通过 class.getDeclaredFields();
和访问私人成员,class.getFields()
但我正在寻找私人继承的字段.我怎样才能实现这一目标?
所以这看起来非常基本,但我无法让它发挥作用.我有一个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反射器可以很好地看到静态属性,所以很明显我在这里遗漏了一些东西.
我想动态解析一个对象树来做一些自定义验证.验证并不重要,但我想更好地理解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对象中找出它的类型.
我将不得不处理基本的东西,如字符串,整数,双打.但我也必须处理对象,如果是这样,我将需要在对象树中进一步向下遍历这些对象以验证其中的基本数据,它们也将具有字符串等.
谢谢.
PHP中是否有任何反射/内省/魔术可以让你找到定义特定类(或函数)的PHP文件?
换句话说,我有一个PHP类的名称,或一个实例化的对象.我想将此传递给某些东西(函数,Reflection类等),它将返回定义类的文件系统路径.
/path/to/class/definition.php
Run Code Online (Sandbox Code Playgroud)
我意识到我可以使用(get_included_files())获取到目前为止已包含的所有文件的列表,然后手动解析它们,但这是一次尝试的大量文件系统访问.
我也意识到我可以在我们的__autoload机制中编写一些额外的代码来缓存这些信息.但是,在我想到的情况下,修改现有的__autoload是不受限制的.
听说可以做到这一点的扩展会很有趣,但我最终会喜欢可以在"库存"安装上运行的东西.
我在命名空间中有几个静态类,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方法.
reflection ×10
c# ×5
.net ×4
java ×3
appdomain ×2
assemblies ×1
class ×1
dynamic ×1
inheritance ×1
php ×1
static ×1