【问题标题】:Extension method for classes implementing an interface实现接口的类的扩展方法
【发布时间】:2018-05-22 03:50:25
【问题描述】:

我正在尝试为所有实现接口Iinterface 的类创建一个扩展方法,该方法将返回T 列表,其中T 是原始类。所以基本上是这样的:

public static List<T> Funct<T>(this T obj)
where T : Iinterface, new()

但这适用于每个对象,而不仅仅是Iinterface 类。因此,我正在尝试制作类似this Iinterface obj 的东西,但只有当我将其用作myObj.Funct&lt;MyObjType&gt;() 时,我才能直接将其用作List&lt;MyObjType&gt; list = myObj.Funct(),但不是。有什么办法可以让我使用这样的扩展程序吗?

我正在考虑使用实用函数或扩展Iinterface 来创建类似这样的东西:

interface IExtend<T> : Iinterface
where T : IExtend<T> {}

然后我可以做一个这样的扩展函数:

public static List<T> Funct<T>(this IExtend<T> obj)
where T : IExtend<T> {}

但是在我这样做之前,有没有办法可以直接将函数实现到Iinterface 对象?

更新 使用示例:

public interface Iinterface { }
public interface Iinterface2 { }


public class MyObjType : Iinterface { }

public class SomeOtherClass : Iinterface2 { }

public static class Mine {


    public static List<T> Funct<T>(this T obj)
    where T : Iinterface, new() => null;

    public static void Funct(this Iinterface2 obj)
    {  }

    public static void Main()
    {
        MyObjType obj = new MyObjType();
        List<MyObjType> list = obj.Funct(); // the above mentioned function works in this case

        SomeOtherClass obj2 = new SomeOtherClass();
        obj2.Funct(); // uses the wrong extension function
    }

}

更新 2

我注意到一些使用不同的答案和建议。所以只是为了澄清:

我明白使用不同的结构可以获得输出。我也已经有了。但是,我一直在寻找是否有一种方法可以使结构适用于这种特定用途。主要原因是这是我发现的最简单的用法,我的主要目标是以最简单的方式实现此功能。 所以基本上我正在寻找 obj.Funct() 和 obj2.Funct() 的确切用法,而不需要传递泛型或参数。

【问题讨论】:

  • 编辑您的问题以显示一个完整的示例,我们可以将其复制并粘贴到 Visual Studio 中,说明您将如何使用此扩展方法,以及它出现但您不希望它出现的情况。列出所有类型名称并避免在您的示例中使用var。
  • 点了。谢谢
  • 你的问题不是特定于扩展方法的问题,任何函数的重载解析都会表现得完全相同,完全匹配被认为是比泛型匹配“更好”的匹配。
  • 我的主要问题是第一个扩展将适用于任何类。 obj2 是我可能面临的问题之一。我也不希望Funct() 出现在每个类的对象中
  • 我的代码气味雷达已经脱离了屋顶。当您遇到这样的情况时,通常表明您应该退后一步并重新考虑您的设计。此外,如果没有更多上下文,就不可能为您提供帮助。函数有什么作用?只是创建一个列表?有什么逻辑吗?

标签: c# generics interface extension-methods


【解决方案1】:

使用接口的全部意义在于隐藏实现的细节,所以你应该考虑做这样的事情:

public static List<Iinterface> Funct(this Iinterface obj) 
{
    var list = new List<Iinterface>();
    //Add your logic here.
    return list;
}

然后像这样消费它:

MyObjType obj = new MyObjType();
List<Iinterface> list = obj.Funct();

【讨论】:

  • 我需要对原始类型的引用。还需要创建该类型的新对象。这就是为什么new()
  • @NevilleNazerane:提供一个更完整的示例,以便我们为您提供帮助。
【解决方案2】:

不是最好的,但你可以这样做:

public static List<T> Funct<T>(this T obj, Iinterface type)
    where T : Iinterface, new()

public static void Funct(this Iinterface2 obj, Iinterface2 type)

这些第二个参数只是在这里帮助您的编译器。 但是,您必须将对象作为参数传递两次,这很麻烦。

public static void Main()
{
    MyObjType obj = new MyObjType();
    List<MyObjType> list = obj.Funct(obj); // still works as expected

    SomeOtherClass obj2 = new SomeOtherClass();
    obj2.Funct(obj2); // uses the correct one, now
}

但是,恕我直言,最好的解决方案是更改您的扩展名。

返回列表的方法和不返回列表的方法。显然,他们不做同样的工作。

那么,为什么它们的名字完全一样?

【讨论】:

  • 感谢您的回答。但是,如果我在函数中提到一个参数,我不妨提一个泛型(我的问题第二段中提到的方式),考虑到它更安全。
  • 关于方法名称,它们做同样的工作并且都返回一个列表。我真的简化了我的代码,因为它被分散了,而且非常值得分享。
  • @NevilleNazerane - “我真的简化了我的代码,因为它被分散了,而且非常值得分享。” - 我们不在乎它有多大,如果您没有提供最少量的代码来演示您的问题,那么您需要显示更多代码。你需要一个minimal reproducible example。
  • 代码完全可以运行,显示实际问题。我的意思是我删除了与问题无关的所有方面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多