Class <t>和static Class,Best Practices?

时间:2016-09-01 13:49:06

标签: c# design-patterns static constants generic-type-argument

我有一个场景(简化)如下:

public static class Example
{
    public const int CONSTANT_VALUE = 1;

    public static Example<T> Create<T>(IEnumerable<T> argument)
        where T : class
    {
        return new Example<T>(argument);
    }

    //More overloads of Create<T>, possibly other static methods, etc..
}

public class Example<T>
    where T : class
{
    public Example(IEnumerable<T> argument)
    {
        //Do Stuff

        //Nothing like this in the real code, just example
        //that constants are used from the other class.
        if (something == Example.CONSTANT_VALUE)             
        {
            //Do A Thing
        }
    }

    //Lots more code
}

基本思想是我可以通过静态类通过类的名称获得静态方法,常量等,而实际的实现是在类型参数化的非静态类中。

我的问题是这是否是一个很好的方法来设置它。有没有办法放置一些不关心Example<T>类型参数的静态方法和常量?是否有更推荐的模式?我的工作得很好,但我想知道是否有其他方法,因为这是我第一次做这样的事情(不是说它在概念上对我来说是新的,只是从来没有需要)。

2 个答案:

答案 0 :(得分:1)

这只有在常量是公开的情况下才有意义。如果它们仅供Example<T>内部使用,那么这是毫无意义的,因为您可以在没有完全限定名称的情况下引用它们。

如果常量是公共使用的,我不会使用这种模式; ExampleExample<T>是两个不同的类,它可能会让任何用户感到困惑,而且非常明显,非泛型类中定义的常量可以适用于通用类。

你只是在用户点击一些按键,我不确定它是否值得。

更新:其他选项

在这种情况下,我将使用以下工厂模式(假设用户在程序集之外)

public class Example<T>
{
     internal Example() { } //disallow users from instantiating this class
      ...
}

public static class Example
{
    public const int Constant = ...
    public static Example<T> Create<T>() { return new ... }
}

现在,所有用户都只与Example进行互动,并避免使用Example<T>。您甚至可以对自己的程序集的用户强制执行此操作,您只需要使Example<T>成为实现公共接口的私有嵌套类:

 public interface IExample<T>
 {
     ...
 }

 public static class Example
 {
     private class Example<T>: IExample<T> { ... }
     public static IExample<T> Create<T>() { ... }
     ....
  }

答案 1 :(得分:-1)

除非有理由不适用于您的情况,否则我宁愿使用非静态基类Example,然后让Example<T>继承此类。这样,您就可以直接访问Example中的所有方法,而无需使用该名称进行限定。当然,这假设Example类专门用于与各种类型的类Example<T>相关联。