c# - 向上转换为通用类型

标签 c# c#-4.0

我有以下类层次结构:

class A {
 /// stuff
}

class B : A {
 /// stuff
}

class C<T> : B {
  /// stuff
}

然后在完全不同的地方我有以下三种方法:

public void foo(A a) {
}

// overload 1
public void bar(B b) {
}

// overload 2
public void bar<T>(C<T> ct) {
}

现在,无论出于何种原因,我需要在给定 A 的实际类型的情况下从 foo 调用“正确的”栏。也就是说,如果 A 实际上是 B 类型,我需要调用重载 1 并且如果 A 实际上是输入 C(无论 T 是什么),我需要调用重载 2。为了完整起见,如果 A 既不是 B 也不是 C,则什么也不做。

现在,我正在使用 Type 类的 IsAssignableFrom 方法来决定是否可以向上转换为 B:

public void foo(A a) {
   if (typeof(B).IsAssignableFrom(a)) {
      bar((B)a);
   }
}

但这也包含 C 变体。所以问题是,我如何执行此向上转换?反射?动力学?我们使用的是 .NET 4,因此我无法使用 C# 5 中引入的任何内容。

最佳答案

Then somewhere completely different I have the following three methods:

这说明了您的问题的第一个潜在解决方案。不要在“完全不同的地方”这样做。制作bar A 的虚拟成员(member)并且有 foo调用它。

第二种可能的解决方案是使用访问者模式。

interface IVisitor
{
    void Visit(B b);
    void Visit<T>(C<T> c);
}
class A 
{
    public virtual void Accept(IVisitor v)
    { } // Do nothing
}
class B : A
{
    public override void Accept(IVisitor v)
    { v.Visit(this); }
}
class C<T> : B 
{
    public override void Accept(IVisitor v)
    { v.Visit<T>(this); }
}
class P
{
    class Visitor : IVisitor
    {
        public void Visit(B b) { bar(b); }
        public void Visit<T>(C<T> c) { bar<T>(c); }
    }
    public static bar(B b) { }
    public static bar<T>(C<T> c) { }
    public static void foo(A a)
    {
        a.Accept(new Visitor());
    }
}

但假设您无法修改 A , BC<T> .

Now, for whatever reason, I need to call the "right" bar from foo given the actual type of A. That is, if A is actually of type B, I need to call overload 1 and if A is actually of type C (whatever T may be), I need to call overload 2. And for completeness, if A is not either B or C, do nothing.

第一个很简单:

public void foo(A a) 
{
    if (a is B) bar((B)a);

但是,泛型子类型很难;没有 if (a is C<?>) bar((C<?>)a; 的机制很遗憾。

您将不得不处理反射或 dynamic .请注意,如果 dynamic无法找到匹配的 bar在运行时它会抛出,而不是什么都不做。

关于c# - 向上转换为通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21294240/

相关文章:

linq - Entity Framework Extended - 简单删除给我空引用

c# - 2D Passes.apply() XNA 4.0

c# - 为什么 HttpClient.PostAsync() 没有在控制台应用程序中完成,但在 Web 应用程序中完成?

asp.net - EF4慢关联访问

c# - 如何将 HttpRequest 接收到 MVC 3 Controller 操作中?

c#-4.0 - JSON.Net SerializeXnode 排除某些节点

c# - 在 Xamarin UITableViewCell 中向 UILabel 添加中心约束不会使标签居中

c# - 当我在 sql server 或 oracle 中运行 havey 查询时如何增加 progressBar?

c# - LINQ - 为匿名类型的只读属性赋值

c# - .NET 4.0 比早期版本慢,这是真的吗?