配置StatePrinter仅遵循声明的类型? [英] Configure StatePrinter to only follow the declared types?

查看:113
本文介绍了配置StatePrinter仅遵循声明的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Stateprinter 打印/比较我的类型.效果很好,但是它确实比较了每个(子)对象的 actual 类型,而不是子对象的声明类型.

I'm using Stateprinter to print/compare my types. It works quite nicely, however, it does compare the actual type of each (sub) object instead of the declared type of the subobject.

一个例子:

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的所有公共字段和属性,而不是仅显示通过IMyData可见的公共状态.

This will print all the public fields and properties of MyDataWithMoreStuff instead of only the public state visible via IMyData.

是否可以使用Stateprinter做到这一点,或者如果当前尚未实现,甚至有可能使用C#反射遍历任意对象的成员树"并处理字段不是通过它们在运行时所具有的具体类型,而是通过(基本/接口)类型来声明变量?

Is there a way to do this with Stateprinter, or if that is currently not implemented, is it even possible using C# reflection to walk the "member tree" of an arbitrary object and treat the fields not by the concrete types that they have at runtime, but by the (base / interface) types the variables are declared with?

推荐答案

从v2.1.xx版本开始,您现在可以基于其他类型指定类型的投影. IE.执行以下操作

As of v2.1.xx you can now specify projections of types based on other types. Ie. do the following

    [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);
    }

但这是基于类型的过滤,而不是基于引用类型的状态的一般收集.那,我认为代码现在不可能是这样的:

but this is filtering based on types, not a general harvesting of state based upon reference types. That, I don't think it is possible the way the code is now:

 class IntroSpector  
 {
    void Introspect(object source, Field field)
    {
        if (IntrospectNullValue(source, field))
            return;

        var sourceType = source.GetType();

        ...

因此StatePrinter要求提供基础类型(GetType()).您可能需要重载该方法,或者可能会更好,编写一个带有第三个参数(引用参数)的ReferenceAwareIntrospector并对其进行处理.

so StatePrinter asks for the underlying type (GetType()). You probably need to overload the method or maybe better, code a ReferenceAwareIntrospector which takes a third parameter, the reference parameter, and works with that.

做到这一点应该很容易,并且使内省器可配置也是Configuration类的简单扩展.

It should be fairly easy to do this and making the introspector configurable is likewise an easy extension of the Configuration class.

这篇关于配置StatePrinter仅遵循声明的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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