使用反射设置私有字段,没有错误但字段始终是旧值

问题描述 投票:0回答:1

我使用带有默认会话存储的 ASP.NET,并且

HttpContext.Session
返回
DistributedSession
的实例(https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/Session/src/分布式会话.cs).

这似乎会加载一次所有会话值,并且有一个私有字段

_loaded
如果我希望
LoadAsync
再次从存储中实际加载,则需要将其设置为 false。

会话按预期工作,因此配置没有任何问题。

显然这是不好的做法,还有另一个合适的解决方案,但忽略我更感兴趣的要求,为什么私有字段始终无法保持我设置的值?

    public class SomeClass
    {
        private readonly IHttpContextAccessor _accessor;

        public SomeClass(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        private async Task SomeMethod()
        {
            var session = _accessor.HttpContext.Session;

            var loadedFlag = session.GetType().GetField("_loaded", BindingFlags.NonPublic | BindingFlags.Instance);

            loadedFlag.SetValue(session, false); // doesn't throw

            var isLoaded = loadedFlag.GetValue(session); // still true?

            await session.LoadAsync();
        }
    }
c# asp.net .net reflection
1个回答
0
投票

我相信这是由于传入值类型(即

false
)而不是将其装箱为对象(也不是很好,但是是的......就是这样)。

object boxedValue = (object)false;
loadedFlag.SetValue(session, boxedValue); // hopefully still doesn't throw
var isLoaded = loadedFlag.GetValue(session); // hopefully now false?

来自医生

例如,如果字段的类型是布尔值,则传递具有适当布尔值的对象实例

© www.soinside.com 2019 - 2024. All rights reserved.