C# 静力法的合理运用

C# 静力法的合理运用,c#,static,static-methods,oop,C#,Static,Static Methods,Oop,从概念上讲,当静态方法(C#)只接受输入并将输入重新格式化为输出时,是否适合使用该方法?例如: public static string FormatString(string inputString){ return "some formatting" + inputString + "Some other formatting"; } 如果我有这些类型的方法中的一些,静态“实用程序”类是个好主意吗?如果您要公开这些方法,那么是的,创建某种实用程序类可能会更好 也就是说,我会尽量使它成为

从概念上讲,当静态方法(C#)只接受输入并将输入重新格式化为输出时,是否适合使用该方法?例如:

public static string FormatString(string inputString){
  return "some formatting" + inputString + "Some other formatting";
}

如果我有这些类型的方法中的一些,静态“实用程序”类是个好主意吗?

如果您要公开这些方法,那么是的,创建某种实用程序类可能会更好


也就是说,我会尽量使它成为“通用”的,因为否则,它们往往很快就无法维护。

是的,如果您有几个通常相关的静态方法,将它们放在一个静态实用程序类中是个好主意


如果您谈论的是约定,那么还值得注意的是,大多数.NET代码中的命名约定都要求使用Pascal大小写的公共成员(因此
FormatString
而不是
FormatString
)和驼峰大小写的参数和字段(因此
inputString
而不是
inputString
),在C#中使用静态方法的方式与C++的“自由函数”思想非常相似。碰巧C#没有自由函数。Eric Lippert在这里的某个地方有一篇有趣的帖子,解释了为什么会这样。静态类用于对具有类似实用程序的函数进行分组,如果您有几个类似的函数,则该类是合适的。

是的,这很好,然后您的类将充当相关函数的“库”。对此,您的其他选择是要么用各种函数污染全局名称空间,要么创建一个不需要的单例,因为没有“状态”来解释

就我个人而言,我更倾向于使用扩展方法,尽管它仍然是静态的;)


是的,你可以这样做。或者您可以创建一个字符串扩展方法

对于上面的示例,我将使用字符串格式化程序而不是内联连接

string.Format("some formatting {0} some other formatting", inputString )

如果这种特殊的格式在代码中的多个位置都有用,那么这就是问题所在

如果它只在一个特定的类中有意义,那么我宁愿使用私有方法(静态或实例,它不会有什么区别)


实用程序类是一个有用的东西。你唯一应该注意的是不要经常使用它们。如果您的大多数代码都在实用程序类中,那么您就做错了。但是在helper方法中分解出一些常见代码是一种完全合理的用法。

您可以为此使用扩展方法来扩展String类。这会使调用代码更加整洁,但最终这只是个人品味的问题

    public static string MyWeirdFormat(this string str)
    {
        return string.Format("{0} is weird",str);
    }

    public static void Test()
    {
        string myString = "ABCD";
        string weirdString =  myString.MyWeirdFormat();
    }

到目前为止,我同意其他答案,这在很多时候都是有意义的

有时,您可能希望通过定义一个接口并使用实例方法实现该接口,从而为自己提供更多的灵活性。这使您可以选择在以后的代码中使用不同的方法

这里有一个例子来说明我的意思。假设您在某些代码中使用了您的
formatString
方法,如下所示:

public void DumpToConsole()
{
    foreach (DataField field in m_fields)
    {
        Console.WriteLine(StringUtils.formatString(field.ToString()));
    }
}
好的,这太好了。(事实上,这很愚蠢,但不管怎么说,都只是为了说明!)但是你可以让这种方法更灵活,让它接受一个接口,你可能有各种各样的实现,提供完全不同的格式:

public void DumpToConsole(IFormatter<DataField> formatter = null)
{
    // Perhaps you could specify a default. Up to you.
    formatter = formatter ?? Formatter<DataField>.Default;

    foreach (DataField field in m_fields)
    {
        Console.WriteLine(formatter.Format(field));
    }
}
public void DumpToConsole(IFormatter formatter=null)
{
//也许你可以指定一个默认值。由你决定。
格式化程序=格式化程序??格式化程序。默认值;
foreach(m_字段中的数据字段)
{
Console.WriteLine(formatter.Format(字段));
}
}
然后,与其说
StringUtils
是一个静态实用程序类,不如说它只是一个类的实现,该类提供了一种格式化特定类型对象的方法(在您的例子中是
string
对象;在我的示例中,这些虚构的
数据字段
对象)

所以这是一种冗长的说法,视情况而定。如果你的目标是实现超级灵活性,也许你应该考虑实现一个接口,而不是使用一个静态助手类。
请注意,在我上面的示例中,处理问题的另一种完全可以接受的方法是接受
Func
委托,而不是这个假设的
IFormatter
接口。在我看来,这主要是一种风格选择。但是,当您想要自定义多个行为时,接口通常会变得更加真实;i、 例如,与接受单个接口相比,定义接受3、4或更多委托的方法可能很快变得麻烦。

在我看来,答案是肯定的,您可以将这些方法放在实用工具(Util)类中。在我目前正在开发的基于Java web的应用程序中,我们实际上有3个这样的UTL类,每个类只包含与您所展示的类似的静态方法。我们有3个的原因是一个只用于客户端的Util方法,一个只用于服务器,第三个用于共享Util方法

取决于你的应用程序是什么,你可能会得到类似的结果

另外,如果您想了解更多关于何时在C#中使用静态类的信息,请看一看


我希望这充分回答了您的问题。

FYI:方法参数应以小写字母开头。(例如,
inputString
)如果您想遵循标准的C#大小写规则,方法名称也应该以大写字母开头。)方法名称应该以大写字母开头(即
FormatString
),假设您遵循.NET编码约定:-->抱歉,当我在“建议编辑”中看到该编辑时,我还没有意识到您就是OP。我以为有人在修改你的代码。谢谢你的评论。我编辑以使套管与最佳实践保持一致。我感谢你的帮助!丹,虽然我同意你所说的精神(就像我通常对什么做的那样)
public void DumpToConsole(IFormatter<DataField> formatter = null)
{
    // Perhaps you could specify a default. Up to you.
    formatter = formatter ?? Formatter<DataField>.Default;

    foreach (DataField field in m_fields)
    {
        Console.WriteLine(formatter.Format(field));
    }
}