在重载方法中使用泛型类型

Den*_*zil 5 c# generics overloading

我有一个通用方法:

public bool DoSomething<T>(T item) where T: IBase
{
    return DoSomethingSpecific(item);
}

public bool DoSomethingSpecific(IBase item)
{
    return true;
}

public bool DoSomethingSpecific(IAdvanced item)
{
    return false;
}
Run Code Online (Sandbox Code Playgroud)

请注意,IAdvanced 接口派生/继承自 IBase 接口。

我发现,如果我在项目类型为 IAdvanced 的情况下调用 DoSomething,它仍然总是返回 false。我不明白这一点。我知道,由于 IAdvanced 是 IBase 类型(因为它是此接口的子级),因此可能会导致 DoSomethingSpecific 方法的 2 个重载类型之间发生混淆。然而,据我所知,以我有限的 C# 知识,这里应该选择 IAdvanced 方法。这是我如何得出这个结论的一个例子:

public class Advanced: IAdvanced
{

   public void CallMethod()
   {
      DoSomething(this);
   }
}
Run Code Online (Sandbox Code Playgroud)

这会产生真实值。

但是,如果我这样做:

public class Advanced: IAdvanced
{

    public void CallMethod()
    {
       DoSomethingSpecific(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

它返回 false,这正是我所期望的。

我不得不说我以前从未使用过泛型。我虽然尝试过,但总是陷入这样的情况,然后完全看不到使用泛型的意义(除了树和链表等数据结构之外)。

这次我决定来这里寻求一些建议。我想做的事情有明显的问题吗?尝试做我在这里忙着做的事情也许没有意义吗?

Ivo*_*Ivo 1

据它所知,它是一个 IBase。编译器需要决定您要调用哪个方法,这就是它总是选择该方法的原因。

\n\n

一个肮脏的伎俩是这样做:

\n\n
public static bool DoSomething<T>(T item) where T: IBase\n{\n    var isAdvanced = typeof(IAdvanced).IsAssignableFrom(typeof(T));\n    return isAdvanced ? DoSomethingSpecific((IAdvanced)item) : DoSomethingSpecific(item);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

另一种方法是使用双调度/访问者模式:

\n\n
public interface IDoSomethingVisitor\xc2\xa0{\n    bool DoSomethingSpecific(IBase base);\n    bool DoSomethingSpecific(IAdvanced adv);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

DoSomething 方法将位于您的 IBase 接口中:

\n\n
public interface IBase{\n    void DoSomething(IDoSomethingVisitor visitor);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在您的实现中:

\n\n
public class Base : IBase\n{\n   public bool DoSomething(IDoSomethingVisitor visitor)\n   {\n      visitor.DoSomething(this);\n   }\n}\n\npublic class Advanced : IAdvanced\n{\n   public bool DoSomething(IDoSomethingVisitor visitor)\n   {\n      visitor.DoSomething(this);\n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这种情况下,使用纯继承就可以解决问题。实际实例是决定调用哪个方法的实例。没有如果。

\n