0

我想编写一个静态实用程序类,它只有一组属性,向用户公开功能

例如我可以打电话:

Utils.String.GetHexString("Hello World");

或者

Utils.Stream.CopyBytes(instream, outstream);

我可以将其比作最接近的是 System.Text.Encoding ,其中有 UTF8、ASCII 等属性,因此您可以调用如下内容:

Encoding.UTF8.GetBytes("Hello World");

或者

Encoding.ASCII.GetBytes("Hello World");

问题在于,在编码中,这调用了对用户公开可用的等效对象 ( UTF8Encoder, )。ASCIIEncoder我想要的是仅通过 Utils 公开对象,而不显示与属性相关的对象,例如

我可以打电话:

Utils.Stream.CopyStream(instream, outstream);

但我不能打电话:

StreamUtils.CopyStream(instr, outstr) //This class is only accessible via the Utils class!

这是否可能,如果是,这样做是好还是坏?

4

5 回答 5

5

这是一个想法:

public interface IStreamUtil
{
    void CopyStream(Stream int, Stream out);
}

internal class StreamUtil : IStreamUtil
{
    // Implementation
}

public static class Util
{
    private static IStreamUtil stream = new StreamUtil();
    public static IStreamUtil Stream 
    {
        get { return stream; }
    }
}

然而,对我来说,这有点奇怪。我个人更喜欢实用程序功能的扩展方法:

inStream.CopyStreamTo(outStream);
myString.GetHexString();

这也可以被认为是不好的,特别是考虑到扩展方法发现和解析算法。好的 ol'StreamUtil.Copy()在大多数情况下都很好。

于 2012-08-03T15:31:06.127 回答
1

无法阻止任何用户创建您StreamUtils类型的变量,例如分配从您的Utils.Stream属性中检索到的值。

但是,有两种解决方案:

  1. 您可以通过创建构造函数来阻止用户StreamUtils自己创建您的类的实例internal。像这样,只有您的Utils类(您可以授予其内部访问权限,无论是通过将其放在同一个程序集中还是使用InternalsVisibleTo属性)可以实例化您的StreamUtils类,而您的库的用户只能使用您的实例的功能,但是无法创建自己的实例。

  2. 另一种方法是使用公共嵌套静态类。在你的Utils类中,你可以声明一个嵌套的公共静态类Stream,它提供你需要的静态方法。像这样,用户不能实例化他们自己的Stream实例(因为它是静态的),并且至少在 C# 中,你甚至会强制用户总是写Utils.Stream来访问你的方法,如果那是你真正想要的。但是请注意,如果您决定将静态类与属性 getter 或其他任何东西交换,这种方法似乎不像第一种方法那么干净,并且会导致重大更改(至少在二进制级别上)。

于 2012-08-03T15:33:47.920 回答
0

好的,基本上不可能(至少在 C# 中)完全实现我想要的。该类必须是可见的,功能才能通过 Util 类可见。

我的解决方案是将类(例如StreamUtilsStringUtils)变成单例。它们不能被构造,因为它们的构造函数是内部的。他们的方法是公开的,但永远看不到,因为无法在我的程序集之外实例化该对象。Utils 类通过单例实例向用户公开功能。

考虑以下:

class StreamUtils
{
    static StreamUtils instance;

    internal static StreamUtils Instance
    {
        get
        {
            if(instance == null)
            {
                instance = new StreamUtils();
            }
            return instance;
        }
    }

    internal StreamUtils()
    {
    }

    public void CopyStream(Stream input, Stream output)
    {
    }
}

static class Utils
{
    public StreamUtils Stream
    {
        get
        {
             return StreamUtils.Instance;
        }
    }
}
于 2012-08-15T22:12:49.450 回答
0

您想要的是可能的,但您不应将Utils其视为一个类本身,而应将其视为包含一些静态实用程序类的命名空间:

namespace Utils
{
    public static class String
    {
        public static string GetHexString(string input)
        {
            ...
        }
    }

    public static class Stream
    {
        public static void CopyBytes(System.IO.Stream instream, System.IO.Stream outstream)
        {
            ...
        }
    }
}

这是否是推荐的做法,是一个完全不同的问题。太多静态实用程序类的问题在于,您不能通过使用依赖注入来实现松散耦合。这会使编写好的单元测试变得更加困难。

于 2012-08-03T15:35:40.900 回答
0

看看你想要达到的目标,我建议,尝试开发扩展方法。

扩展方法使您能够将方法“添加”到现有类型,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但它们被称为扩展类型的实例方法。

阅读此处提供的超链接的更多信息。

于 2012-08-03T15:36:08.873 回答