将 StatePrinter 配置为仅遵循声明的类型?
Configure StatePrinter to only follow the declared types?
我正在使用 Stateprinter 来 print/compare 我的类型。它工作得很好,但是,它确实比较每个(子)对象的 实际 类型而不是子对象的声明类型。
一个例子:
class X {
string Foo;
int Bar;
}
interface IMyData {
public X MyConfig { get; }
}
现在,调用时:
var cfg = ConfigurationHelper.GetStandardConfiguration();
cfg.Add(new PublicFieldsAndPropertiesHarvester());
var printer = new Stateprinter(cfg);
// ...
IMyData v = new MyDataWithMoreStuff();
printer.PrintObject(v);
这将打印 MyDataWithMoreStuff
的所有 public 字段和属性,而不仅仅是通过 IMyData
.
可见的 public 状态
有没有办法用 Stateprinter 做到这一点,或者如果目前没有实现,是否有可能使用 C# 反射来遍历 "member tree"任意对象,而不是根据它们在运行时具有的具体类型来处理字段,而是根据变量声明的(基本/接口)类型?
从 v2.1.xx 开始,您现在可以根据其他类型指定类型的投影。 IE。执行以下操作
[Test]
public void TestIncludeByType()
{
var sut = new AtoD();
Asserter assert;
assert = TestHelper.CreateShortAsserter();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA>();
assert.PrintEquals("new AtoD() { A = 1 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA, IB>();
assert.PrintEquals("new AtoD() { A = 1 B = 2 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA, IB, IC>();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA, IB, IC, ID>();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut);
}
[Test]
public void TestExcludeByType()
{
var sut = new AtoD();
Asserter assert;
assert = TestHelper.CreateShortAsserter();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA>();
assert.PrintEquals("new AtoD() { B = 2 C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA, IB>();
assert.PrintEquals("new AtoD() { C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA, IB, IC>();
assert.PrintEquals("new AtoD() { D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA, IB, IC, ID>();
assert.PrintEquals("new AtoD() { }", sut);
}
但这是基于类型的过滤,而不是基于引用类型的一般状态收集。那,我不认为现在的代码是这样的:
class IntroSpector
{
void Introspect(object source, Field field)
{
if (IntrospectNullValue(source, field))
return;
var sourceType = source.GetType();
...
因此 StatePrinter 要求提供基础类型 (GetType()
)。您可能需要重载该方法,或者可能更好,编写一个 ReferenceAwareIntrospector
代码,它接受第三个参数,即引用参数,并使用它。
这样做应该相当容易,并且使内省器可配置同样是 Configuration
class.
的简单扩展
我正在使用 Stateprinter 来 print/compare 我的类型。它工作得很好,但是,它确实比较每个(子)对象的 实际 类型而不是子对象的声明类型。
一个例子:
class X {
string Foo;
int Bar;
}
interface IMyData {
public X MyConfig { get; }
}
现在,调用时:
var cfg = ConfigurationHelper.GetStandardConfiguration();
cfg.Add(new PublicFieldsAndPropertiesHarvester());
var printer = new Stateprinter(cfg);
// ...
IMyData v = new MyDataWithMoreStuff();
printer.PrintObject(v);
这将打印 MyDataWithMoreStuff
的所有 public 字段和属性,而不仅仅是通过 IMyData
.
有没有办法用 Stateprinter 做到这一点,或者如果目前没有实现,是否有可能使用 C# 反射来遍历 "member tree"任意对象,而不是根据它们在运行时具有的具体类型来处理字段,而是根据变量声明的(基本/接口)类型?
从 v2.1.xx 开始,您现在可以根据其他类型指定类型的投影。 IE。执行以下操作
[Test]
public void TestIncludeByType()
{
var sut = new AtoD();
Asserter assert;
assert = TestHelper.CreateShortAsserter();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA>();
assert.PrintEquals("new AtoD() { A = 1 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA, IB>();
assert.PrintEquals("new AtoD() { A = 1 B = 2 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA, IB, IC>();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.IncludeByType<AtoD, IA, IB, IC, ID>();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut);
}
[Test]
public void TestExcludeByType()
{
var sut = new AtoD();
Asserter assert;
assert = TestHelper.CreateShortAsserter();
assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA>();
assert.PrintEquals("new AtoD() { B = 2 C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA, IB>();
assert.PrintEquals("new AtoD() { C = 3 D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA, IB, IC>();
assert.PrintEquals("new AtoD() { D = 4 }", sut);
assert = TestHelper.CreateShortAsserter();
assert.Project.ExcludeByType<AtoD, IA, IB, IC, ID>();
assert.PrintEquals("new AtoD() { }", sut);
}
但这是基于类型的过滤,而不是基于引用类型的一般状态收集。那,我不认为现在的代码是这样的:
class IntroSpector
{
void Introspect(object source, Field field)
{
if (IntrospectNullValue(source, field))
return;
var sourceType = source.GetType();
...
因此 StatePrinter 要求提供基础类型 (GetType()
)。您可能需要重载该方法,或者可能更好,编写一个 ReferenceAwareIntrospector
代码,它接受第三个参数,即引用参数,并使用它。
这样做应该相当容易,并且使内省器可配置同样是 Configuration
class.