替代:静态类作为泛型参数

本文关键字:泛型 参数 静态类 替代 | 更新日期: 2023-09-27 18:17:19

我确实有很多代表不同模块中不同状态的静态类。然而,它们共享提取其信息的通用算法。

public static class Constants
{
    public static readonly int A = 0;
}

现在我为每个类设置了多个静态函数。它们的区别只在于所处理的静态类的类型(及其总体名称)。

public static SelectListItem getConstantsSelectListItem()
{ // pseudo example
     return new SelectListItem { Text = "A" , Value = Constants.A };
}

为了消除当前和避免未来的代码膨胀,我想对静态类使用反射。我的方法是这样的(如果可能的话):

public static ReturnType getProperties< T >()
{ // basically same logic as getConstantsSelectListItem
    var propertyList = typeof( T ) .GetFields( BindingFlags.Public | BindingFlags.Static ).ToList();
    foreach( var item in propertyList )
    {
        var curConstant = (int)( item.GetValue( null ) );
        // do some work here..
    }
}
var constantsProperties = getProperties<Constants>();

错误是:

static types cannot be used as argument types

我读到过,对于泛型只能使用实例(因此不能使用静态类)。

让类似的东西工作的好方法是什么?

替代:静态类作为泛型参数

c# -静态类型不能用作类型参数的问题很好地说明了这种行为是有意为之的。

它没有告诉你应该做什么。在我看来,您可以使用单例模式来保留该类的一个实例。这样做的一个好处是,您也可以使用继承,因此您不需要反射来完成您现在所做的技巧,您可以只依赖基类的方法签名。

您可以将Type对象作为参数传递,而不是使用泛型。因为无论如何你都必须执行typeof(T) .GetFields(,这并不意味着你失去了任何静态类型安全。

我强烈提出的另一个建议是使用字典将字符串映射到整数来表示常量集合。像这样使用反射只会毫无理由地给你带来痛苦,对开发人员强制执行奇怪的、几乎是仪式性的规则("这个静态类很神奇,不要添加任何字符串"),并且性能更差。