【问题标题】:Is there an alternative to Inheritable static generic classes in C#?在 C# 中是否有替代可继承静态泛型类的方法?
【发布时间】:2013-09-30 20:57:01
【问题描述】:

我想要一系列静态类,每个类都包含一个字典并在字典上执行两种方法。除了一个方法中的参数类型和另一种方法中的返回类型之外,所有版本的类中的方法都是相同的。

理想情况下,我想将行为(方法)放在“基础”通用静态类中,然后创建几个类型化的 static 后代,每个后代都包含自己的静态字典。显然,我不能这样做,因为一个静态类不能从另一个静态类继承。

我想知道是否有其他方法可以实现我的目标。我知道我可以使用非静态类来完成这项工作,但在我看来这更适合静态任务。

这是我想要的草图:

public static class BaseClass<T>
{
  private static Dictionary<string, T> PrivateDict {get; set;}

  private static String ToString(T argument)
  {
     return Somestring;
  }

  private static T FromString(string argument)
  {
     return Some-T-thing;
  }
}

// This static class supplies the static dictionary but gets the static methods of BaseClass.
// Other static classes might exit that use, for instance, Dictionary<string, XElement>
public static class GenderClass : BaseClass<int>
{
  private static Dictionary<string, int> PrivateDict = new Dictionary<string, int>
  {
      {"Male", 1},
      {"Boy", 1},
      {"M", 1},
      {"Female", 2},
      {"Girl", 2},
      {"F", 2}
  }
}

【问题讨论】:

  • 为什么没有一个静态类,其中基类有一个静态成员,子类有一个静态成员?
  • 我最近问了一个类似的问题:stackoverflow.com/questions/18895395/… 这可能是相关的。

标签: c# generics inheritance static


【解决方案1】:

我建议使用类型作为“继承”的路径。我之所以这么说,是因为它实际上只是一种绕过方式,但它仍应以您想要的类似方式工作。

我在 LinqPad 中对此进行了测试,它产生了正确的结果,没有抛出异常。请注意,这些字段是为了测试目的而公开的。

首先,设置一个可以用来传递字典的接口。

public interface IPublicDictionary<T>
{
 Dictionary<string, T> PublicDictionary { get; }
}

接下来,设置你的类(非静态),它将实现接口并公开一个唯一的字典

public class GenderClass : IPublicDictionary<int>
{
 public static Dictionary<string, int> PublicDict = new Dictionary<string, int>
 {
  {"Male", 1},
  {"Boy", 1},
  {"M", 1},
  {"Female", 2},
  {"Girl", 2},
  {"F", 2}
 };

 public Dictionary<string, int> PublicDictionary
 {
  get { return PublicDict; }
 }
}

现在该类已准备好在已成为主要工作场所的静态基类中使用。

public static class BaseClass
{
 public static String ToString<F,T>(F argument) where T : IPublicDictionary<F>, new()
 {
  IPublicDictionary<F> t = new T();
  return t.PublicDictionary.First(d => Comparer<F>.Equals((F)d.Value, argument)).Key;
 }

 public static F FromString<T,F>(string argument) where T : IPublicDictionary<F>, new()
  {
   IPublicDictionary<F> t = new T();
   return t.PublicDictionary[argument];
  }
}

设置完成后,剩下的就是简单地调用基类。这是我尝试的两个示例。

var s = BaseClass.FromString<GenderClass,int>("F");
Console.WriteLine(s);
var t = BaseClass.ToString<int,GenderClass>(2);
Console.WriteLine(t);

哪些输出

2
Female

【讨论】:

  • 在这个解决方案中,每次我想将字符串转换为性别时,我似乎都在实例化 GenderClass 的一个实例,反之亦然。此代码将用于 ETL 工作,可能有数十万次调用,所以我担心开销。
【解决方案2】:

关于某事物是否应该是静态的决定与您将要使用它的方式有关。如果你必须在那里有一些静态的东西,我个人会这样做:

  • 有一个逻辑接口。然后根据需要创建尽可能多的类来实现它,每个类都专门处理逻辑。如果有任何共享逻辑,则可以创建一个非静态的基本抽象类,并根据需要再添加尽可能多的子类。
  • 在静态类的给定方法中,根据您获得的参数选择您希望使用的逻辑实现类。然后实例化所选类的对象,调用相关方法,并返回其结果。

即:像这样:

public interface foo
{
    string ToString(someBase input);
    someBase FromString(string input);
}

public static class Bar
{
    public static string ToString(someBase input)
    {
        if (input.GetType() == typeof(Duck))
        {
            foo duckie = new DuckHandler();
            return duckie.ToString(input);
        }
        else if (input.GetType() == typeof(DeadParrot)) { /* ..snip.. */ }
    }

    public static someBase FromString(string input, type Type) {
        if (type == typeof(Duckie))
        {
            foo duckie = new DuckHandler(input);
            return duckie;
        }
        else if (type == typeof(OKLumberjack)) { /* ..snip.. */ }
    }
}

你可以看到它的去向。

【讨论】:

    猜你喜欢
    • 2012-11-12
    • 2023-04-03
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2021-07-28
    相关资源
    最近更新 更多