如何使用泛型在 C# 中将类型静态绑定在一起(如在 TypeToType <T>中)?

How can you statically bind types together (as in TypeToType<T>) in C# using generics?

本文关键字:TypeToType lt gt 如在 在一起 泛型 何使用 静态绑定 类型      更新时间:2023-10-16

假设我有一套形式为BooleanAttributeContinuousAttributeFiveStarAttribute等的类型。每个类型在概念上都绑定到一个值类型(例如,对于上面的示例,booldoubleint。)每个类型还继承自一个公共基类AttributeBase

假设我有另一个名为AttributeUpgrade<Attr>的泛型类,它包含Attr的一个实例作为成员,其中Attr继承自AttributeBase。我还希望它包含概念上绑定到Attr的值类型的两个实例(旧实例和新实例)。

对于C++模板,这将是微不足道的。在Attribute套件中的每个类型中,我都会为ValueType定义一个typedef,并将我的成员声明为

template <typename Attr>
class AttributeUpgrade
{
Attr attribute;
typename Attr::ValueType old; 
typename Attr::ValueType new;
...

到目前为止,C#中的等效解决方案或任何接近它的解决方案都暗示了我。任何解决方案都将受到赞赏,即使它们涉及到撕裂示例中的一些结构。就目前情况来看,我正朝着放弃打字安全的方向前进,只把旧的和新的作为对象打字。非常感谢。

试试这个:

class AttributeUpgrade<T> where T : Attr
{
T oldOne; 
T newOne;
}

请注意,new是一个保留关键字。

where子句是可选的,但您可能希望将使用的类型限制为Attr

编辑:为了清楚起见,我省略了类和成员上的访问说明符,因为我不知道需要什么访问级别。

编辑:评论答案:

换句话说:您希望在AttributeUpgrade的声明中重用Attr中的模板参数,而不向AttributeUpdate引入新的通用参数。

这在C#中无法完成。

您将需要第二个模板参数,或者在Attr的内部类型上使用GetType()来获得System.Type(但正如您所知,这里没有类型安全性)。C++通过在类中使用typedefs来解决这个问题。这里最接近的是别名,但它们无法提供您需要的功能。

请参阅stackoverflow.com/questions/1990556/csharp-typedef-generics。

事实上,我认为这里"最好"的方法是添加另一个模板参数,并在运行时(!)断言Attr的内部类型等于AttributeUpgrade中的内部类型。

您似乎正在尝试使用C#泛型编写C++模板。然而,它们在概念和执行上都有点不同。你到底想创造什么?你最初要解决的问题是什么?

如果我理解您的意图,那么简单的解决方案就是让AttributeBase本身具有通用性。

class AttributeBase<T>
{
T value;
}
class BooleanAttribute: AttributeBase<bool>
{
}
class AttributeUpgrade<T> 
{
AttributeBase<T> attribute;
T oldValue;
T newValue;
}
// Or alternatively...
class AttributeUpgrade<T, K>
where T : AttributeBase<K>
{
T attribute;
K oldValue;
K newValue;
}

如果你负担不起使用泛型基类的费用,你可以根据需要使用接口来重新定义一些东西(即,要么有一个泛型模板,要么有非泛型类,反之亦然),但我预计情况并非如此,因为C++模板也会有同样的问题。

与模板不同,C#泛型是在运行时按需解析的,它们不仅仅是编译过程中的预处理步骤。这当然有其优点和缺点,而且它们根本不是一回事。这并不意味着你不能使用泛型来解决你在C++中用模板解决的问题,但这不仅仅是C++中的语法糖。您可以使用代码生成器来做一些类似C++模板的事情,但这超出了SO问题的范围:D