【问题标题】:(Why) is invoking as extension method the preferred...way?(为什么)作为扩展方法调用是首选的……方式?
【发布时间】:2017-01-21 07:50:41
【问题描述】:

我正在使用刚刚发布的 Resharper (2016.2.2) 版本重新锐化我的解决方案

它标记了这行代码:

ReportRunnerConstsAndUtils.ConvertValueToAppropriateTypeAndAssign(totalPackagesCell, packages);

...暗示我应该“作为扩展方法调用

如果我默认,它会将该行更改为:

totalPackagesCell.ConvertValueToAppropriateTypeAndAssign(packages);

这样更好吗?如果是这样,怎么做?为什么?

这是被调用的方法,它位于“ConstsAndUtils”类中:

// Adapted from https://stackoverflow.com/questions/26483496/is-it-possible-to-ignore-excel-warnings-when-generating-spreadsheets-using-epplu
public static void ConvertValueToAppropriateTypeAndAssign(this ExcelRangeBase range, object value)
{
    string strVal = value.ToString();
    if (!String.IsNullOrEmpty(strVal))
    {
        decimal decVal;
        double dVal;
        int iVal;

        if (decimal.TryParse(strVal, out decVal))
            range.Value = decVal;
        if (double.TryParse(strVal, out dVal))
            range.Value = dVal;
        else if (Int32.TryParse(strVal, out iVal))
            range.Value = iVal;
        else
            range.Value = strVal;
    }
    else
        range.Value = null;
}

【问题讨论】:

  • 它在我看来确实更干净更清晰。不过,ReSharper 提出了许多偏好类型的建议。如果您不喜欢它,您应该可以在选项中将其关闭。
  • 正如 itsme86 所说,这是个人喜好... ReSharper 还可以选择执行反向重构“将扩展方法转换为纯静态”jetbrains.com/resharper/features/…
  • 这是基于意见的。没有更好的方法可以做到这一点。大多数人认为扩展方法看起来更干净,但仅此而已。关于您发布的代码,double.TryParse 何时会被成功调用? (顺便说一句,你错过了else)。
  • 我想说,如果将静态方法制成扩展方法,那么调用它是有意义的,因为它会产生更简洁的代码。另一方面,如果无论出于何种原因,以这种方式调用没有意义,那么问题可能在于该方法首先不应该是扩展方法。
  • @InBetween:谢谢,但为什么 double.TryParse 有问题?

标签: c# resharper extension-methods resharper-2016


【解决方案1】:

建议您将其作为扩展方法调用,因为您(或某人)将其创建为扩展方法。语法this ExcelRangeBase range 使该方法成为扩展方法,因此为了保持一致性,在调用它时应该将其用作扩展方法。否则,您会有读取 ReportRunnerConstAndUtils.ConvertValueToAppropriateTypeAndAssign(range) 的行和读取 range.ConvertValueToAppropriateTypeAndAssign() 的行。

C#6 引入了一些新语法,现在您可以在文件顶部添加 using ReportRunnerConstAndUtils,然后在调用站点添加 ConvertValueToAppropriateTypeAndAssign(range)。

【讨论】:

  • 好的,谢谢;让我感兴趣的是,当我这样做时,我不再需要指定扩展方法在哪里。以“错误”的方式进行操作,我必须在方法名称前面加上“ReportRunnerConstsAndUtils”(包含公共方法的 .cs 文件);以“正确”的方式进行操作,这是不必要的。我并不是真的在抱怨,但我想知道为什么。
  • @B.ClayShannon:原因是因为 C# 与 VB 不同,不会自动将所有静态类拉入作用域,因此在给定方法(参数)语法的情况下,编译器实际上找不到匹配的方法。这是一个设计选择,他们用 C#6 稍微调整了它,您现在可以指定一个要拉入范围的类,它可以在没有类名的情况下找到它。
【解决方案2】:

作为一个基于意见的问题,它并不能真正回答,但我想指出以下几点。

在这种特殊情况下,我不会使用扩展方法,因为该方法返回void;不返回某些内容并仅导致副作用的方法不是很好的扩展方法候选者,我发现它们作为标准静态方法调用更具可读性。

我尽量保持我的扩展方法“纯粹”,但就像我说的,这是我个人的意见。

如果您考虑一下,实现了扩展方法以使 LINQ 成为可能,这是 C# 的一个非常实用的方面。我倾向于在我实现的任何扩展方法中保持相同的“感觉”。

【讨论】:

  • 我不认为 OP 的问题是基于意见的。 OP 询问为什么 Re-Sharper 提出这个建议。 Re-Sharper 根据个人喜好提出建议这一事实并非意见。
  • @devlincarnate Resharper 提出的建议显然是一个事实,我并不是说这是一个基于意见的问题,但如果你仔细阅读 OP 的问题,你会注意到他也是询问为什么、如何以及是什么让 Resharper 的建议变得更好,而这些更重要问题的答案是基于意见的。
【解决方案3】:

正如一些 cmets 所指出的,这至少部分是偏好问题。就个人而言,我认为在这里使用扩展方法更“干净”和清晰,但有些人可能不同意这一点。

“在幕后”,当然,扩展方法是一个静态方法(不是实际的实例方法),只是编译器在这里给了你一些语法糖(但这不是重点)。

【讨论】:

    猜你喜欢
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多