无法使用反射访问运行时缓存 [英] Can't Access Runtime Cache Using Reflection

查看:49
本文介绍了无法使用反射访问运行时缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据此答案,我正在尝试获取 HttpRuntime.Cache 对象的到期日期:

https://stackoverflow.com/a/350374/1778169

方法是:

 私有DateTime GetCacheUtcExpiryDateTime(字符串cacheKey){对象cacheEntry = Cache.GetType().GetMethod("Get",BindingFlags.Instance | BindingFlags.NonPublic).Invoke(缓存,新对象[] {cacheKey,1});PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires",BindingFlags.NonPublic | BindingFlags.Instance);DateTime utcExpiresValue =(DateTime)utcExpiresProperty.GetValue(cacheEntry,null);返回utcExpiresValue;} 

当我尝试使用上述方法时,第一行将无法编译:

object.GetType()需要对象引用

如果我将 Cache.GetType()替换为 HttpRuntime.Cache.GetType(),它将编译,但是我从此部分返回null:

cacheType.GetMethod("Get",BindingFlags.Instance | BindingFlags.NonPublic).

我在做什么错了?

我正在使用.NET 4.5.System.Web.Caching是版本4.0.0.0.

解决方案

您应该已经使用网站查询了原始源 Microsoft安装程序,以查找 HttpRuntime 类的更多详细信息,特别是 Cache 属性.如果您查看System.Web.HttpRuntime类的第2794行您可以看到 Cache 属性的以下定义:

 公共静态缓存缓存{得到 {...}} 

现在,由于属性为 static ,您不能使用正在使用的绑定标志,因为现在您正在查找属于 NonPublic 成员实例.在.NET中,静态变量不属于实例,因此您发布的代码将导致引发异常.它根本找不到您要查找的成员,因为它在您提供的实例中不存在-但是它确实存在于您要查找的类的类型定义( HttpRuntime )上.

为了使您的代码正常工作,您将需要省略绑定标志,现在,处理您的请求的内部.NET代码将了解我们正在尝试查找静态方法: HttpRuntime.Cache.GetType().GetMethod("Get").注意:如果要具有绑定标志(可读性,可理解性),则可以添加: BindingFlags.Public |BindingFlags.Static ,它与您省略标志时的作用完全相同.

如果要执行该方法并获取结果(获取实际的 Cache ),则可以调用刚从 GetMethod收到的 MethodDefinition .使用 Invoke(null,null).

I am trying to get the expiry date of a HttpRuntime.Cache object, as per this answer:

https://stackoverflow.com/a/350374/1778169

The method is:

private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
    object cacheEntry = Cache.GetType().GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Cache, new object[] { cacheKey, 1 });
    PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
    DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);    
    return utcExpiresValue;
}

When I try to use the above method, the first line won't compile:

An object reference is required for object.GetType()

If I replace Cache.GetType() with HttpRuntime.Cache.GetType() it compiles, but I get null returned from this part:

cacheType.GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic).

What am I doing wrong?

I am using .NET 4.5. System.Web.Caching is version 4.0.0.0.

解决方案

You should have looked up the original source using the website Microsoft setup in order to find out more details of the HttpRuntime class, specifically the Cache property. If you look at line 2794 of the System.Web.HttpRuntime class you can see the following definition of the Cache property:

 public static Cache Cache {
        get {
              ...
        }
 }

Now since the property is static you cannot use the binding flags you are using, since right now you are looking for a NonPublic member that belongs to an Instance. In .NET static variables don't belong to an instance, therefor the code you posted will result in an exception being thrown; it simply cannot find the member you are looking for, since it not exists on the instance you provided -- it does however exists on the type definition of the class you are looking into (HttpRuntime).

In order to make your code work you will need to omit the binding flags, the internal .NET code that handles your request will now understand we are trying to lookup a static method: HttpRuntime.Cache.GetType().GetMethod("Get"). Note: if you want to have bindingflags (readability, understandabilty), you could add: BindingFlags.Public | BindingFlags.Static, which exactly does the same as whenever you omit the flags.

If you want to execute the method and get the result (get the actual Cache) you can invoke the MethodDefinition you just received from the GetMethod using Invoke(null, null).

这篇关于无法使用反射访问运行时缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆