在运行时访问 DisplayClass 对象的 属性
Accessing property on DisplayClass object at runtime
环境: VS2017,C# 7.0 针对 .NET Core 2.1。
我正在尝试编写 fake/mock class 用于单元测试,但我在访问 DisplayClass
对象上的 属性 时遇到困难,我的理解是 a closure class from an anonymous function.
我的代码如下所示:
namespace MyCompany.Application.Web.Test.Fakes
{
public class FakeElasticClient : IElasticClient
{
public FakeElasticClient() { }
public Task<ISearchResponse<T>> SearchAsync<T>(Func<SearchDescriptor<T>, ISearchRequest> selector = null, CancellationToken cancellationToken = default(CancellationToken)) where T : class
{
var methodName = selector.Method.Name;
dynamic tgt = selector.Target;
object id = tgt?.GetType().GetProperty("id")?.GetValue(tgt, null);
int? total;
if (methodName.Contains("Quux"))
{
total = CountSomething((Guid)id);
}
else
{
total = CountSomethingElse((Guid)id);
}
return Task.Run(() => new FakeSearchResponse<T>(total ?? 0) as ISearchResponse<T>);
}
// … below here follows a couple thousand other methods
将 id
转换为 Guid
会引发 NullReferenceException
,即使 Visual Studio 调试器显示 tgt
对象具有 id
属性:
评论:
- 我偷了 this answer 的
object id = …
行。
tgt.GetType()
returns MyCompany.Application.Domain.Repository.Implementations.BusinessEntityRepository.<>c__DisplayClass8_0
tgt.GetType().GetProperties()
returns 空 PropertyInfo
数组。
- 受this blog post的启发,我在
MyCompany.Application.Domain.Repository.Implementations.BusinessEntityRepository
和MyCompany.Application.Web.Controllers
class中添加了一个[assembly: InternalsVisibleTo("MyCompany.Application.Web.Test")]
属性,据我所知是调用链中涉及的仅有的两个 classes。没有任何区别。
- 我试过
IgnoresAccessChecksTo
as described here,但无法编译任何东西。
如何检索 id
的值?
编译器生成带有字段而不是属性的闭包类型,因此 id
是一个字段。请改用 tgt.GetType().GetFields()
。
环境: VS2017,C# 7.0 针对 .NET Core 2.1。
我正在尝试编写 fake/mock class 用于单元测试,但我在访问 DisplayClass
对象上的 属性 时遇到困难,我的理解是 a closure class from an anonymous function.
我的代码如下所示:
namespace MyCompany.Application.Web.Test.Fakes
{
public class FakeElasticClient : IElasticClient
{
public FakeElasticClient() { }
public Task<ISearchResponse<T>> SearchAsync<T>(Func<SearchDescriptor<T>, ISearchRequest> selector = null, CancellationToken cancellationToken = default(CancellationToken)) where T : class
{
var methodName = selector.Method.Name;
dynamic tgt = selector.Target;
object id = tgt?.GetType().GetProperty("id")?.GetValue(tgt, null);
int? total;
if (methodName.Contains("Quux"))
{
total = CountSomething((Guid)id);
}
else
{
total = CountSomethingElse((Guid)id);
}
return Task.Run(() => new FakeSearchResponse<T>(total ?? 0) as ISearchResponse<T>);
}
// … below here follows a couple thousand other methods
将 id
转换为 Guid
会引发 NullReferenceException
,即使 Visual Studio 调试器显示 tgt
对象具有 id
属性:
评论:
- 我偷了 this answer 的
object id = …
行。 tgt.GetType()
returnsMyCompany.Application.Domain.Repository.Implementations.BusinessEntityRepository.<>c__DisplayClass8_0
tgt.GetType().GetProperties()
returns 空PropertyInfo
数组。- 受this blog post的启发,我在
MyCompany.Application.Domain.Repository.Implementations.BusinessEntityRepository
和MyCompany.Application.Web.Controllers
class中添加了一个[assembly: InternalsVisibleTo("MyCompany.Application.Web.Test")]
属性,据我所知是调用链中涉及的仅有的两个 classes。没有任何区别。 - 我试过
IgnoresAccessChecksTo
as described here,但无法编译任何东西。
如何检索 id
的值?
编译器生成带有字段而不是属性的闭包类型,因此 id
是一个字段。请改用 tgt.GetType().GetFields()
。