隐藏静态方法可以吗?

时间:2010-08-18 22:52:53

标签: c# .net class-design static-methods

我有一个抽象的Catalog类,如下所示。它有一个静态方法OpenCatalog(),用于根据提供的位置类型返回特定的具体目录。一旦确定了目录的类型,它就会调用正确的具体目录类型的特定OpenCatalog()方法。例如,我可能有一个存储在SQL数据库中的Catalog实现,或者存储在文件系统中的另一个实现。请参阅下面的代码。

public abstract class Catalog
{
    public static ICatalog OpenCatalog(string location, bool openReadOnly)
    {

        if(location is filePath)
        {
            return FileSystemCatalog.OpenCatalog(string location, bool openReadOnly);
        }
        else if(location is SQL server)
        {
            return SqlCatalog.OpenCatalog(string location, bool openReadOnly);
        }
        else
        {
            throw new ArgumentException("Unknown catalog type","location");
        }
    }

    ...

}

public abstract class FileSystemCatalog:Catalog
{

    public static new ICatalog OpenCatalog(string location, bool openReadOnly)
    {
        //Deserializes and returns a catalog from the file system at the specified location
    }

    ...

}



public abstract class SqlCatalog:Catalog
{

    public static new ICatalog OpenCatalog(string location, bool openReadOnly)
    {
        //creates an returns an instances of a SqlCatalog linked to a database
        //at the provided location          
    }

    ...

}

首先,一般来说隐藏静态方法是否可以?我知道这是可能的,但它也似乎不应该经常做的事情。这也是一个有效的例子,可以隐藏静态方法,还是有更好的方法来做我想做的事情?

3 个答案:

答案 0 :(得分:2)

看起来你正试图以非常尴尬的方式创建abstract factory。实际发生的是您违反Single Responsibility Principle并将目录创建问题与目录问题混合在一起。你需要做的是使CatalogFactory非静态类。这为您提供了以后随意使用的灵活性(例如依赖注入)。

public class CatalogFactory {
  public ICatalog CreateCatalog(string location, bool openReadOnly)
  {

    if(location is filePath)
    {
        return OpenFileCatalog(string location, bool openReadOnly);
    }
    else if(location is SQL server)
    {
        return OpenSqlCatalog(string location, bool openReadOnly);
    }
    else
    {
        throw new ArgumentException("Unknown catalog type","location");
    }
  }
  FileSystemCatalog OpenFileCatalog(string location, bool openReadOnly) {
    return new FileSystemCatalog{/*init*/};
  }
  SqlCatalog OpenSqlCatalog(string location, bool openReadOnly) {
    return new SqlCatalog{/*init*/};
  }

}

答案 1 :(得分:1)

你并没有真正隐藏它,因为你总能做到

Catalog.OpenCatalog(...);

如果你想要基类版本。实际上,静态方法与特定类相关联,而不是虚拟的。您可以在派生类的基类中调用静态方法,这是一个很好的方便。

答案 2 :(得分:0)

我从未在“代码嗅觉”方面发现反对使用私有/内部静态方法的论据。

一个很好的实际示例可能是某种服务/实用程序库中的扩展方法,您只想在该库中扩展。

internal static ShippingRateType ToShippingRateType(this ProviderShippingRateType rateType) { }