【问题标题】:How to combine extension method's this with params keyword?如何将扩展方法的 this 与 params 关键字结合使用?
【发布时间】:2019-02-28 21:37:06
【问题描述】:

我想写一个扩展方法:

static public bool IsKeyPressedAny(this params System.Windows.Input.Key[] keys)
{
    foreach (var key in keys)
    {
        if (System.Windows.Input.Keyboard.IsKeyDown(k))
        {
            return true;
        }
    }
    return false;
}

这样使用

IsKeyPressedAny(Key.LeftShift, Key.RightShift);

IsKeyPressedAny(Key.a)

但是方法的签名无效,在params之前添加this会导致错误CS1104:“A parameter array cannot be used with 'this' modifier on an extension method”。

我目前的解决方法是

static public bool IsKeyPressedAny(
    this System.Windows.Input.Key key
    , params System.Windows.Input.Key[] keys
)
{
    if (System.Windows.Input.Keyboard.IsKeyDown(key)) return true;

    foreach (var k in keys)
    {
        if (System.Windows.Input.Keyboard.IsKeyDown(k))
        {
            return true;
        }
    }
    return false;
}

这让我觉得有点笨拙。有没有办法保持使用 params 的好处,同时避免在签名中重复参数类型?

(一种)解决方案

cmets 让我意识到我在误用 this。由于 this 是作为方法添加到签名中它前面的类型的,因此在 params 之前使用它是无稽之谈。 我试图避免输入包含该方法的类的名称,this 不是解决该问题的方法。

【问题讨论】:

  • 我不认为扩展方法是您正在寻找的。当然,您列出的调用语法与它们的预期用途不同(扩展方法被设计为看起来像您调用的单个实例的“扩展”,如实例方法)。您可能只想要一个带有辅助方法的辅助类。
  • 如果您仍然像常规静态方法一样调用该方法,那么this 毫无意义。要从this 中受益,您必须将其称为Key.LeftShift.IsKeyPressedAny( ... )。因此,请重新考虑您是否真的需要this
  • docs.microsoft.com/en-us/dotnet/csharp/misc/cs1104 有帮助吗?如果删除 this 会发生什么?
  • @mjwills 这不是我想要的。我想写“namespace_name.method_name”而不是“namespace_name.helper_class_name.method_name”。据我了解,使用 static namespace_name.helper_class_name 不允许这样做。

标签: c#


【解决方案1】:

考虑给这个类一个有用的、有点具体的名字,以获得这样的语法:

KeyPressed.Any(Key.LeftShift, Key.RightShift);

实现
public static class KeyPressed
{
    public static bool Any(params System.Windows.Input.Key[] keys)
    {
        ....
    }
}

好吧,这并不能真正回答您的问题,但仍然可能是一个有用的解决方案。

【讨论】:

    【解决方案2】:

    this 将方法添加到它在签名中的前面的类型中,在 params 之前使用它没有任何意义。

    this 并不是为了省去您键入包含该方法的类的名称。

    【讨论】:

      【解决方案3】:

      您要查找的内容称为“使用静态”,它导入的东西就像命名空间的常规 usingdirective:

      using static YourNameSpace.KeyHelpers;
      

      将允许您仅通过其名称调用YourNameSpace.KeyHelpers.IsKeyPressedAny,而无需类名:

      IsKeyPressedAny(Key.LeftShift, Key.RightShift);
      

      例子:

      public static class KeyHelpers
      {
          public static bool IsKeyPressedAny(params System.Windows.Input.Key[] keys)
          {
              foreach (var key in keys)
              {
                  if (System.Windows.Input.Keyboard.IsKeyDown(k))
                  {
                      return true;
                  }
              }
              return false;
          }
      }
      

      【讨论】:

      • 我更喜欢 Stefan 提到的 Any 方法,而不是 IsKeyPressedAny
      • 说实话,我也更喜欢命名变体。但这是 完全 OP 要求的语言功能,所以我认为应该提及它。
      • 谢谢,这个例子让我知道使用静态是如何工作的 :-)
      猜你喜欢
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-07
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多