【问题标题】:C# Generics and Interface Inherits InterfaceC# 泛型和接口继承接口
【发布时间】:2012-04-18 19:36:57
【问题描述】:

假设我有两个接口,IFeaturesA,IFeaturesB。

IFeaturesA 有一组签名方法。假设一个是:-

public void printMe();

IFeaturesB实现了IFeaturesA,并增加了新的签名方法,如:-

public void printMeAlso();

假设我要使用泛型方法,例如:-

public Check<E>(E passedItem)
{

}

如果我传入 IFeaturesA,我希望能够调用 this 的方法。如果我传入 IFeaturesB,我希望能够调用额外的方法 printMeAlso();

在 C# 中检查传递给泛型方法的接口类型并访问其方法的最佳方法是什么?是否针对两种接口类型检查对象类型然后强制转换为最佳方式?

【问题讨论】:

    标签: c# generics interface


    【解决方案1】:

    这不符合泛型

    泛型是对行为的无类型重用。如果您需要检查类型,那么它不适合泛型。您可以强加constraints,但不能在泛型方法中检查实际类型..

    你试图抽象的只是你正在传递一个项目。这不是抽象。

    【讨论】:

    • 好吧,有道理。我想减少必须编写另一种方法来从一个接口调用另一个接口的类似(稍微扩展)函数。但我想如果比较语句可能同样臃肿,我想必须写。
    【解决方案2】:

    使用两种方法

    公共检查(IFeaturesA passItem) {

    }

    公共检查(IFeaturesB 已通过项目) {

    }

    添加私有方法来处理通用性

    【讨论】:

    • 感谢您的所有回答,我同意了,因为这与我最初要做的事情一致,我只是想也许有一种不那么臃肿的方法,但它变成了这同样有效。
    【解决方案3】:

    不要以为通过定义接口就可以达到你想要的效果,简单定义classe结构,比如

    public class FeaturesA
    {
        public virtual void printMe()
        {  
        }
    
    }
    
    public class FeaturesB : FeaturesA
    {
        public override void printMe()
        {  
        }
    
    }
    

    在代码中使用之后,比如

    FeaturesA a = new FeaturesA(); 
    FeaturesA b = FeaturesB();
    public Check(A passedItem)
    {
        passedItem.printMe();
    }
    

    Check(a) 上打印 a,Check(b) 上打印 b

    希望这会有所帮助。

    【讨论】:

    • 我正在使用接口来定义大量其他类的方法签名——即一个具有 printA 功能,下一个具有 printA 和 printB 功能,另一个可能具有 printA 和 printB,但每个类以不同的方式实现该方法。
    • @Davos555:但是从 this 的角度来看,这并没有改变任何东西。你仍然有签名,你仍然可以拥有(如果你需要的话)其他方法,并且你可以使用重载,这是在使用泛型接口无法以你想要的方式实现的情况下。
    • 谢谢 Tigran,只是想解释得更好一点。
    【解决方案4】:

    如果要检查项目的类型,请使用“is”:

    if (passedItem is IFeatureA) { }
    

    如果您想将泛型约束到可由接口或抽象类定义的某些行为,请使用“where”:

    public class foo<E> where E : IFeatureA
    {
    }
    

    后一种情况不允许你使用 IFeatureB,但是类型 E 类中的任何变量都可以使用 IFeatureA 中定义的方法和属性,而无需检查类型。

    您可能还想查看 Dynamic 类型,因为它更接近您想要做的事情。

    【讨论】:

      【解决方案5】:

      我会检查 E 的类型,比如

      if(E.GetType().Equals(typeof(IFeaturesA)){ //call method...}
      

      【讨论】:

        【解决方案6】:

        这看起来像是对另一个接口的调用。

        如果你让两个接口都继承自 IPrintable 只包含一个 Print() 方法,并用 where E : IPrintable 扩展你的 Check&lt;E&gt;(E passedItem),你可以调用 passedItem.Print()

        【讨论】:

          【解决方案7】:

          试试下面的

          Check(IFeaturesA f) {}
          Check(IFeaturesB f){}
          Check<T>(T obj) where T : IFeaturesA, IFeaturesB {}
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-14
            • 1970-01-01
            • 1970-01-01
            • 2013-10-04
            • 2021-10-27
            • 2020-12-01
            相关资源
            最近更新 更多