【问题标题】:Overload extension method for multiple classes多个类的重载扩展方法
【发布时间】:2018-10-23 18:36:18
【问题描述】:

在我的项目中,我有一个代表某种文档类型的类。每个类都有自己的属性和方法,尽管它们之间有一些相似之处。

我正在尝试为每个具有相同名称的类(方法重载)实现一个扩展方法,但我得到一个模棱两可的调用错误

代码进一步解释

文档类型 A 类表示:

static class DocType_A
{
    private static XElement baseDocType_A = XmlFiles[0].Root;

    // Extension Method
    internal static IEnumerable<ViewData> AsViewData(this IEnumerable<XElement> result)
    {
        return
            from doc in result select new ViewData { };
    }


    // Contains methods for querying through the XML file of this [DocType_A] type
    internal static class Query
    {
        internal static IEnumerable<XElement> ByStatusOrAny(byte status = 0)
        {
            return baseDocType_A.Descendants("DocType_A").Select(doc => doc);
        }

        internal static IEnumerable<XElement> Expired()
        {
            return baseDocType_A.Descendants("DocType_A").Where("some conditions").Select(doc => doc);
        }

    }

    // Represents the data needed to be displayed to the user via the DGV
    internal class ViewData
    {
        // [DocType_A] related Property 
    }

    internal class Counter
    {
        // some property
    }

}

文档类型 B 类表示:

static class DocType_B
{
    private static XElement baseDocType_B = XmlFiles[1].Root;

    // Extension Method
    internal static IEnumerable<ViewData> AsViewData(this IEnumerable<XElement> result)
    {
        return
            from doc in result select new ViewData { };
    }


    // Contains methods for querying through the XML file of this [DocType_A] type
    internal static class Query
    {
        internal static IEnumerable<XElement> ByStatusOrAny(byte status = 0)
        {
            return baseDocType_B.Descendants("DocType_B").Select(doc => doc);
        }

        internal static IEnumerable<XElement> Expired()
        {
            return baseDocType_B.Descendants("DocType_B").Where("some conditions").Select(doc => doc);
        }

    }

    // Represents the data needed to be displayed to the user via the DGV
    internal class ViewData
    {
        // [DocType_B] related Property 
    }

    internal class Counter
    {
        // some property
    }
}

用法:

class SomeApplicationClass
{
    void Method()
    {
        IEnumerable<DocType_A.ViewData> query = DocType_A.Query.ByStatusOrAny().AsViewData();
    }

    void SomeOtherMethod()
    {
        IEnumerable<DocType_B.ViewData> query = DocType_B.Query.ByStatusOrAny().AsViewData();
    }
}

但是我得到了模棱两可的调用错误。

是否可以为每个同名的类制作扩展方法?

【问题讨论】:

  • 您尝试做的事情是不可能的,因为您在两个不同的类中定义了相同的扩展方法。扩展方法是完全一样的,为什么不在一个扩展类里面有那个方法呢?无论如何,在您要扩展的类中定义扩展方法是没有意义的......
  • 这并不是我的强项,但在我看来,您正试图在 both 类中定义导致冲突的扩展方法。通常我认为扩展方法是在他们自己的类中定义的。您为 DocType_A 和 DocType_B 使用静态类是否有原因?这当然不是线程安全的,除非这个特定的实现有真正的充分理由,否则您可能会遇到其他困难。
  • @DavidZemens 实际上,我正在尝试在两个类中定义扩展方法,因为我起初认为扩展方法将是类范围的。我将 DocType 类设为静态的原因是由于我的应用程序逻辑,因为这代表了一种文档类型,而不是它的实例,或者我认为。

标签: c# extension-methods overloading


【解决方案1】:

您创建的扩展方法不是用于 Doctype_A 或 Doctype_B,而是为 IEnumerable 创建的。所以你实际上有两个具有相同签名的扩展方法。

如果你想要一个特定于 A 或 B 的,你会这样做

    internal static IEnumerable<XElement> ByStatusOrAny(this DocType_A doc, byte status = 0)
    {
        return doc.Query.Descendants("DocType_A").Select(doc => doc);
    }

然后像这样称呼它

    DocType_A.ByStatusOrAny().AsViewData();

我知道你希望它被限定,但它不是这样工作的。无论 [this] 限定符是什么,扩展方法都将应用于什么,无论它在哪个类中。如果您将每个扩展方法保存在一个不同的命名空间,只在你想要的特定文件中引用你想要的命名空间,但我从未尝试过,所以你的里程可能非常。

另外,正如其他人所指出的,您的示例似乎不适合扩展方法的正常用例。因此,如果这就是你正在做的事情,你可能想要重新设计一些东西。

【讨论】:

    【解决方案2】:

    您正在考虑扩展方法,就好像它们是类方法一样。他们不是。

    它们实际上是一堆静态方法的语法糖,因此编译器和智能感知可以帮助您调用它们。

    您必须使用需要IEnumerable&lt;XElement&gt; 类型参数的函数。编译器应该调用IEnumerable&lt;XElement&gt; 的哪个?对于重载检查的所有意图,“this”参数被忽略。之后,您将拥有两个具有相同名称和任何参数类型的函数来区分。

    【讨论】:

      【解决方案3】:

      我相信你的问题就在这里:

      internal static IEnumerable<ViewData> AsViewData(this IEnumerable<XElement> result)
      

      您在 DocType_B 和 DocType_A 中有一个类似的方法...如果您删除静态,它应该可以工作,但我认为这不是一种方法。

      【讨论】:

      • 根据定义,扩展方法是静态方法。
      猜你喜欢
      • 2015-01-24
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多