0

我有一个愚蠢的小类“ FileSystemSize ”,它既可以用作对象,也可以通过公共的静态方法使用。输出是相似的,但在每种情况下都不相同。

该类最初是静态的,但我添加了将其初始化为对象的可能性,以允许在未来版本中使用新的“便捷方法”进行扩展,而无需进行大量参数解析。例如,我有GetKBString()GetMBString()等...方法可以方便地按照我想要的方式格式化文件大小(作为字符串)。在内部,该类将文件字节大小存储为双精度值。

如果这完全有道理,我有点困惑。看来我应该把它分成一个静态版本和一个对象版本,就像微软为 Directory 和 DirectoryInfo 所做的那样。但是,对我来说,将这一切集中在一个名称不会被弄错的地方似乎更容易——应该清楚 FileSystemSize 的作用是什么?对维护有什么我没有预料到的影响吗?那是什么味道?

var mypath = @"C:\mypath";

var filesystemsize = new FileSystemSize(mypath);
string kilobytes = filesystemsize.GetKBString();
string megabytes = filesystemsize.GetMBString();
double bytes = filesystemsize.ByteSize;

double staticbytes = FileSystemSize.GetDirectoryBytesSize(new DirectoryInfo(mypath));
double statickilobytes = FileSystemSize.ConvertSize(staticbytes, "KB");
4

5 回答 5

2

换个角度看:为什么要将字符串/数字/UI 格式化方法放在 FileSystemSize 方法中?

虽然它可以用于文件,但这是一个通用功能,恕我直言,应该在组织良好的库中的其他地方找到它 - 就像路径函数不是 .net 中的文件或目录类的一部分一样,我会将字符串或数学实用程序类中的“格式化数字”方法。

分离对象的职责,您可能会发现在这种情况下不需要混合静态和非静态成员。

于 2009-09-05T20:22:01.270 回答
1

一个很好的测试:如果你问自己和我们是否还可以,有可能不是。

对于类的用户来说,让一些方法通过类访问而另一些通过对象访问可能是不自然的,尤其是当第二种方法并不真正需要类的实例属性时。他们可能会感到困惑,并会说:“WTF 这个程序员做到了?!”。

如果您喜欢扩展类的可能性,我建议使用所有实例方法,无论是使用扩展方法还是通过子类化。

于 2009-09-05T19:55:26.183 回答
1

由于您在 FileSystemSize 中没有很多状态,这不是扩展方法的完美候选者吗?

我会亲自提供将数字格式化为文件大小字符串的扩展名,并使用 anenum来指定如何格式化文件大小:

public static class FileSystemSize
{
    public static long GetDirectoryBytesSize(string path);
}

public static class NumberExtensions
{
    public static string FormatAsFileSize(
        this long fileSize, FileSizeStringFormat format);
}

public enum FileSizeStringFormat
{
    KiloByte,
    MegaByte,
}
于 2009-09-05T19:56:44.777 回答
1

如果您使用的是 C# 3.0,则可以使用扩展方法和 IFormatProviders 更好地表达您的意图。在代码中,这可能是 FileInfo 和 DirectoryInfo ToString 方法的扩展方法,因此它们会读取如下内容:

var directorySize = myDirectory.ToString("GB");
var fileSize = myFile.ToString("MB");

上面的代码对于您正在尝试做的事情感觉更自然。

看看以下内容如何为您工作。其中一些需要测试(想到递归方法 DirectoryInfoExtender.GetDirectorySize)。如果您需要能够编写类似的语句Console.WriteLine("{0:GB}", fileInfo),您也可以考虑编写 IFormatProvider。

另请注意,对于这些可公开访问的方法,我有意省略了空值检查和异常处理。

public static class DirectoryInfoExtender
{
    public static string ToString(this DirectoryInfo d, string format, int fractionalDigits)
    {
        double fileSize = GetDirectorySize(d);
        return FileSizeConverter.GetFileSizeString(fileSize, format, fractionalDigits);
    }

    public static double GetDirectorySize(DirectoryInfo d)
    {    
        var files = d.GetFiles();
        var directories = d.GetDirectories();

        if(files.Length == 0 && directories.Length == 0)
        {
            return 0;
        }
        else
        {
            double size = 0;

            foreach(var file in files)
            {
                size += file.Length;
            }

            foreach(var directory in directories)
            {
                size += GetDirectorySize(directory);
            }
        }

        return size;
    }
}


public static class FileInfoExtender
{
    public static string ToString(this FileInfo f, string format, int fractionalDigits)
    {
        return FileSizeConverter.GetFileSizeString(f.Length, format, fractionalDigits);
    }
}

public class FileSizeConverter
{
    public static string GetFileSizeString(double fileSize, string format, int fractionalDigits)
    {
        long divisor;
        string sizeIndicator;

        switch(format.ToLower().Trim())
        {
            case "gb":
                divisor = (long)Math.Pow(2, 30);
                sizeIndicator = "gigabytes";
                break;
            case "mb":
                divisor = (long) Math.Pow(2, 20);
                sizeIndicator = "megabytes";
                break;
            case "kb":
                divisor = (long)Math.Pow(2, 10);
                sizeIndicator = "kilobytes";
                break;
            default:
                divisor = 1;
                sizeIndicator = "bytes";
                break;
        }

        return String.Format("{0:N" + fractionalDigits +"} {1}", fileSize / divisor, sizeIndicator);
    }
}
于 2009-09-05T20:21:27.217 回答
0

标准气味是静态方法的使用 - 如果您在整个代码中使用这些方法,这将使其难以维护。

恕我直言,另一个气味是:类名不清楚它的实际作用。根据您的描述,它旨在格式化数据,在这种情况下,我会在类名中提及它。

于 2009-09-05T20:21:04.877 回答