Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在重载方法中使用泛型类型_C#_Generics_Overloading - Fatal编程技术网

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

C# 在重载方法中使用泛型类型,c#,generics,overloading,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; } 这将产生

我有一个通用方法:

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;
}
这将产生一个真实值

但是,如果我这样做:

public class Advanced: IAdvanced
{

    public void CallMethod()
    {
       DoSomethingSpecific(this);
    }
}
它返回false,这是我所期望的

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


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

我无法重现这一点,这意味着可能正在发生其他事情。我怀疑你的意思是说它总是返回真的。这就是我在这里看到的:

using System;

public interface IBase {}
public interface IAdvanced : IBase {}

public class Base : IBase {}
public class Advanced : IAdvanced {}

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

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

    public static bool DoSomethingSpecific(IAdvanced item)
    {
        return false;
    }

    static void Main()
    {
        Console.WriteLine(DoSomething(new Base()));     // True
        Console.WriteLine(DoSomething(new Advanced())); // True
    }    
}
这里的
T
将是
IBase
,但该值将引用
IAdvanced
的实现。如果您希望在这种情况下执行
dosomethingsspecific(IAdvanced)
,并且如果您使用的是C#4,那么您可以使用动态键入:

public static bool DoSomething(IBase item)
{
    dynamic dynamicItem = item;
    // Dispatch dynamically based on execution-time type
    return DoSomethingSpecific(dynamicItem);
}
请注意,该方法如何不再需要是泛型的-它不会带来任何好处

另一方面,如果您想仅仅根据
T
来决定调用哪一个,那么您需要使用类似ivowiblo的解决方案


就我个人而言,我会尽量避免这两种解决方案——我通常会发现,这种情况是一种设计的症状,可以通过其他方式进行改进。

据它所知,这是一种IBase。编译器需要决定调用哪个方法,这就是为什么它总是选择那个方法

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

public static bool DoSomething<T>(T item) where T: IBase
{
    var isAdvanced = typeof(IAdvanced).IsAssignableFrom(typeof(T));
    return isAdvanced ? DoSomethingSpecific((IAdvanced)item) : DoSomethingSpecific(item);
}
剂量测量方法将在IBase界面中:

public interface IBase{
    void DoSomething(IDoSomethingVisitor visitor);
}
在您的实现中:

public class Base : IBase
{
   public bool DoSomething(IDoSomethingVisitor visitor)
   {
      visitor.DoSomething(this);
   }
}

public class Advanced : IAdvanced
{
   public bool DoSomething(IDoSomethingVisitor visitor)
   {
      visitor.DoSomething(this);
   }
}

在本例中,使用纯继承解决了问题。实际实例是解析要调用哪个方法的实例。没有ifs。

我会删除编译时检查并使其运行:

public bool DoSomething(IBase item)
{
    var itemAdvanced = item as IAdvanced;
    if (itemAdvanced != null)
        return DoSomethingSpecific(itemAdvanced);
    else
        return DoSomethingSpecific(item);
}

原因是,如果调用者只静态地知道对象是
IBase
,但在运行时它是一个
IAdvanced
,那么不应该将其视为
IAdvanced
?这可能也是做你想做的事情的最快方法。如果你认为有必要,我只会选择
动态
方法,例如,因为可能有很多不同的方法。

他认为Advanced@ivowiblo当前位置他声称它返回false,但显然不是(参见我的示例)。我添加了一个编辑,解释了为什么期望它返回false是绝望的希望。是的,我期望false。你没有弄错吗??我得到一个false:/我将再次检查我的代码,因为c使用静态绑定,而不是动态绑定。正如Jon所说,调用哪个方法的决定是在编译时完成的,而不是runtime@Denzil:再见。从中可以学到一件事:提供一个简短但完整的例子,可以减少在描述发生的事情时出现混淆的可能性:)谢谢你的建议。我将尝试这样做。我担心使用typeof的性能,但我想我不应该预先优化我将提供一个更复杂的选项,但更好的设计您建议使用双重分派/访问者模式非常好。我已经实现了一半。我没有想到实现访问者,相反,我必须为基类的每个新派生反复更新我的接口。只有在我接受了蒂姆的回答后,我才看到这一点。我想我可能更喜欢这个。我要试试看!这位来访者工作得棒极了。我将其应用于一个基类是抽象的情况,因此我将DoSomething方法抽象,这迫使我为每个具体类创建公共bool DoSomething(IDoSomethingVisitor)。然而,我想知道,所有的方法都是完全相同的(在每种情况下,关键字“this”指的是其他的东西)。难道没有更好的方法可以做到这一点,这样我就不必为每个具体的类实现这个方法吗?这是因为它们看起来都一样,
这个
有不同的含义,被调用的方法是不同的。也许这没有回答我明确提出的问题,但它肯定回答了我想问的问题。非常感谢,我要用这个。它看起来干净简单,而且我相信它在性能方面不会太难。
public interface IBase{
    void DoSomething(IDoSomethingVisitor visitor);
}
public class Base : IBase
{
   public bool DoSomething(IDoSomethingVisitor visitor)
   {
      visitor.DoSomething(this);
   }
}

public class Advanced : IAdvanced
{
   public bool DoSomething(IDoSomethingVisitor visitor)
   {
      visitor.DoSomething(this);
   }
}
public bool DoSomething(IBase item)
{
    var itemAdvanced = item as IAdvanced;
    if (itemAdvanced != null)
        return DoSomethingSpecific(itemAdvanced);
    else
        return DoSomethingSpecific(item);
}