【问题标题】:How to call an extension method without using如何在不使用的情况下调用扩展方法
【发布时间】:2013-07-24 03:15:11
【问题描述】:
using System;

class Runner
{
    static void Main()
    {
        A a = new A();
        // how to say a.PrintStuff() without a 'using'
        Console.Read();
    }
}

class A { }

namespace ExtensionMethod
{
    static class AExtensions
    {
        public static void PrintStuff(this A a)
        {
            Console.WriteLine("text");
        }
    }
}

如何在没有“使用”的情况下调用扩展方法?而不是 ExtensionMethod.AExtensions.PrintStuff(a),因为它没有使用扩展方法。

【问题讨论】:

  • 为什么反对添加 using 语句?
  • 使用您的代码,您不能。对不起。 c# 编译器需要知道在哪里可以找到扩展方法。如果它在单独的命名空间中,则需要using,没有办法。
  • @BillGregg 只是好奇有没有办法......
  • 可以直接调用ExtensionMethod.AExtensions.PrintStuff(a)
  • @BillGregg 也许不是 OP 的意图,但我搜索了这个问题,因为我想从 VS 的即时窗口调用扩展方法。

标签: c#


【解决方案1】:

可以像这样直接调用你的扩展,因为它只是一个静态方法,传递它将作为第一个 this 参数作用的实例:

A a = new A();
ExtensionMethod.AExtensions.PrintStuff(a);

如果您遵循此模式获取更常用的扩展方法,这可能会让其他遇到此代码的开发人员感到困惑。它还会使链接扩展调用(例如 LINQ)看起来更像是一种函数式语言,因为您将嵌套每个调用而不是链接它们。

【讨论】:

  • 当您不想导入与您已导入的其他命名空间有很多冲突的命名空间时,此方法非常有用。
【解决方案2】:

如果扩展方法和类 A 在同一个命名空间中,这是可能的,

如果你必须使用不同的命名空间,那么你必须使用using,我认为没有using 就没有办法做到这一点。但是您可以通过将所有扩展名放在一个命名空间中来减少 using 的数量,例如 Linq (System.Linq.Extensions)

注意:您可以删除扩展方法的命名空间,然后它将使其全局可用

【讨论】:

  • 甚至不知道不需要命名空间:)
【解决方案3】:

它需要using 才能知道函数所在的位置。 Linq 中的一个例子。如果没有使用 System.Linq - 您将不会为您的任何IEnumerable<T>'s 启用 linq

但是,您可以在与调用者相同的命名空间中定义扩展方法,以避免放入 using。但是,如果在许多命名空间中都需要这种方法,则该方法将不起作用

【讨论】:

    【解决方案4】:

    这让我觉得很脏,但是您可以将扩展方法放在 System 命名空间中。 此命名空间默认包含在您的问题中

    using System;
    
    class Runner
    {
        static void Main()
        {
            A a = new A();
            // how to say a.PrintStuff() without a 'using'
            Console.Read();
        }
    }
    
    class A { }
    
    namespace System
    {
        static class AExtensions
        {
            public static void PrintStuff(this A a)
            {
                Console.WriteLine("text");
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      关于创建类型ExtendableType的扩展方法的思考:

      • 将类命名为 ExtendableTypeExtensions
      • 声明扩展类partial,以便客户端可以按照相同的模式添加扩展方法;和
      • 将扩展方法放在与基类型相同的命名空间中

      除非您有充分的理由遵循 LINQ 之类的模型:

      • 大量扩展方法,
      • 所有这些都适用于多个基类。

      【讨论】:

        【解决方案6】:

        您可以添加没有命名空间的扩展方法。 这会影响整个系统,不建议这样做。

        public static class StringExtensions
        {       
            public static void HelloWorld(this String s)
            {
                Console.Write("Hello World");
            }
        }
        
        
        
            string str = "s";
            str.HelloWorld();
        

        【讨论】:

          【解决方案7】:

          在我们的项目中,扩展被放置在与类扩展相同的命名空间中。你的例子:

          A.cs:
          using System;
          namespace ANamespace
          {
          
               class A { }
          }
          
          AExtensions.cs:
          namespace ANamespace
          {
              static class AExtensions
              {
                  public static void PrintStuff(this A a)
                  {
                      Console.WriteLine("text");
                  }
              }
          }
          

          现在,当您为 ANamespace 添加 using 以使用 A 类时,A 类的所有扩展也将包括在内。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-27
            • 2011-11-29
            • 2018-05-10
            • 1970-01-01
            • 1970-01-01
            • 2015-07-02
            相关资源
            最近更新 更多