无法使用反射访问运行时缓存 [英] Can't Access Runtime Cache Using Reflection
问题描述
根据此答案,我正在尝试获取 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
,您不能使用正在使用的绑定标志,因为现在您正在查找属于的
.在.NET中,静态变量不属于实例,因此您发布的代码将导致引发异常.它根本找不到您要查找的成员,因为它在您提供的实例中不存在-但是它确实存在于您要查找的类的类型定义( NonPublic
成员实例 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屋!