如何"偷偷摸摸"第三方对象背后的界面

Mat*_*ius 4 c# interface .net-4.5

我有工作C#,.NET 4.5.
我有2个对象(实际上更多但为了简单起见,我们坚持使用两个)是独立的实体,并且都来自第三方库,但它们确实具有很少的共同属性.

我想做一个可以使用这些属性的抽象机制.如果这些对象是我的,我可以通过添加界面轻松完成

class Foo : IFooBar
{
    public string A { get; set; }
    public string B { get; set; }
}

class Bar : IFooBar
{
    public string A { get; set; }
    public string B { get; set; }
}

interface IFooBar
{
    string A { get; set; }
    string B { get; set; }
}

public static class Extensions
{
    public static IFooBar ProcessedFoobars(IFooBar fooBar)
    {
    ...(do things to A and B)
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,由于他们来自第三方,我没有(不知道)将它们置于界面之后的方式.

选项我看到ATM:

  1. 转换FooBarMyFooMyBar被我的内部放置物体MyFooMyBar背后接口和处理它们这样

  2. 使用仅接受属性作为输入的方法.

    Tuple<string, string> DoThings(string A, string B)
    {
    ...(do things to A and B)
    }
    
    Run Code Online (Sandbox Code Playgroud)

这将涉及来自第三方对象的每种风格的大量映射.

  1. 在这一点上,我倾向于使用反射.

    public T FooBarProcessor<T>(T fooBar)
    {
        var type = typeof (T);
        var propertyA = type.GetProperty("A");
        var propertyB = type.GetProperty("B");
        var a = propertyA.GetValue(fooBar, null);
        var b = propertyB.GetValue(fooBar, null);
        ... (do things to A and B)
        propertyA.SetValue(fooBar, a);
        propertyB.SetValue(fooBar, b);
        return fooBar;
    }
    
    Run Code Online (Sandbox Code Playgroud)

有没有办法'隐藏'第三方对象(或其他一些解决方法)背后的界面,这将允许我让多个对象看起来好像是在界面后面,所以我可以用同样的方式处理它们.

是什么让我希望能够做到这一点 - PostSharp确实允许在付费版本中进行'Aspect继承'(我自己没有尝试过,所以它可能有所不同),如果他们以某种方式这样做 - 那么这个可以做到.

Ufu*_*arı 9

你需要的是适配器模式.

您可以创建实现您的界面的类,并在后台使用Foo和Bar:

interface IFooBar
{
    string A { get; set; }
    string B { get; set; }
}

class FooAdapter : IFooBar
{
    private readonly Foo _foo;

    public FooAdapter(Foo foo)
    {
        _foo = foo;
    }

    public string A
    {
        get { return _foo.A; }
        set { _foo.A = value; }
    }

    public string B
    {
        get { return _foo.B; }
        set { _foo.B = value; }
    }
}


class BarAdapter : IFooBar
{
    private readonly Bar _bar;

    public BarAdapter(Bar bar)
    {
        _bar = bar;
    }

    public string A
    {
        get { return _bar.A; }
        set { _bar.A = value; }
    }

    public string B
    {
        get { return _bar.B; }
        set { _bar.B = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)