如何使用泛型在 C# 中将类型静态绑定在一起(如在 TypeToType <T>中)?
How can you statically bind types together (as in TypeToType<T>) in C# using generics?
假设我有一套形式为BooleanAttribute
、ContinuousAttribute
、FiveStarAttribute
等的类型。每个类型在概念上都绑定到一个值类型(例如,对于上面的示例,bool
、double
、int
。)每个类型还继承自一个公共基类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
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 如何显式调用运算符<<
- 模板操作员&lt;未打电话
- C / CUDA中的模板方法是3个角括号(&lt;&lt;&lt;)
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 左角支架解释为操作员&lt;而不是模板参数
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- 超载操作员&lt;&lt; - 必须是二进制操作员
- 没有匹配的“运营商&lt;&lt;”