2

假设我有这些类层次结构:

public abstract class Parent {
}

public class A : Parent {
    public void Update() { }
}

public class B : Parent {
    public void Update() { }
}

public class C : Parent {
    public void Update() { }
    public void Update(bool force) { }

}

正如你所看到的,所有的后代Parent都有一个更新方法,没有参数。

我想创建一个可以与任何类型的Parent对象一起使用并Update在进程结束时调用的实用程序类。我确信 Update 方法会被实现,所以我写了这段代码:

public class ParentUtilities {
    private static readonly Dictionary<Type, MethodInfo> g_UpdateMethods = new Dictionary<Type, MethodInfo>{
        { typeof(A), typeof(A).GetMethod("Update", new Type[] {})},
        { typeof(B), typeof(B).GetMethod("Update", new Type[] {})},
        { typeof(C), typeof(C).GetMethod("Update", new Type[] {})}
    };

    public static void DoSomething(Parent p)
    {
          CalculateTheMeaningOfTheLife(p);             

          g_UpdateMethods[p.GetType()].Invoke(p, null);
    }
}

因为我无法控制类层次结构(它来自第 3 方程序集)。我只能更改实用程序类。我怎样才能避免这种调整?

由于我坚持使用 .Net 3.5 SP1,因此我无法使用动态。

4

4 回答 4

5

您可以在不触及这些类的情况下做的一件事是创建自己的界面IUpdateable,然后创建自己的新并行层次结构,如

interface IUpdateable
{
    void Update();
}

public class A : Original.A, IUpdateable {}

如果您随后可以使用自己的叶类而不是原始类,则可以将该方法编写为接受IUpdateable参数。但是,虽然使用您自己的类并不是很困难(using 别名指令可以提供帮助),但生成它们并不是那么容易(您需要在每次调用创建原始类的任何实例的原始库之后插入自定义代码,如果该实例在Parent您回到第一格时输入)。

不要忘记在看到原始代码的作者时也对其进行迫害。

于 2012-06-26T10:26:35.833 回答
2

您可以创建一个具有良好定义的接口实现的包装类。

用法

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        IUpdatable wrapper = new AWrapper(a);
        wrapper.Update(); // prints A.Update
    }
}

包装类和接口

interface IUpdatable
{
    void Update();
}


public abstract class Parent { }

public class A : Parent
{
    public void Update()
    {
        Console.WriteLine("A.Update");
    }
}

public class AWrapper : IUpdatable
{
    public A Inner { get; private set; }
    public AWrapper(A a)
    {
        Inner = a;
    }

    public void Update()
    {
        Inner.Update();
    }
}
于 2012-06-26T10:42:53.337 回答
1

如果只有一组已知的(非常)小的子类,那么您可以执行以下操作:

public class ParentUtilities
{
    public static void DoSomething(Parent p)
    {
        CalculateTheMeaningOfTheLife(p);

        var a = p as A;
        if (a != null)
        {
            a.Update();
            return;
        }

        var b = p as B;
        if (b != null)
        {
            b.Update();
            return;
        }

        var c = p as C;
        if (c != null)
        {
            c.Update();
            return;
        }
    }
}
于 2012-06-26T10:27:54.757 回答
0

创建一个名为 UpdatableParent 的临时类,其中包含一个 Update() 方法,并从中派生所有其他类。然后使用 UpdateableParent 作为 DoSomething() 参数的类型。

于 2012-06-26T10:27:56.170 回答