用C#泛型专门化一个值? 我有一些C++代码,它实现了基本的像素类。以下是我掌握的一些重要信息: // Pixel.h template <class SizeType> struct Pixel { public: typedef SizeType Size; Size R; Size G; Size B; static Size Min; static Size Max; TPixel(Size R = Min, Size G = Min, Size B = Min); }; #include "Pixel.impl" // Pixel.impl template <class SizeType> SizeType Pixel<SizeType>::Min = std::numeric_limits<Size>::min(); template <class SizeType> SizeType Pixel<SizeType>::Max = std::numeric_limits<Size>::max(); template <> float Pixel<float>::Min = 0; template <> float Pixel<float>::Max = 1; template <> double Pixel<double>::Min = 0; template <> double Pixel<double>::Max = 1; //Pixel.h 模板 结构像素 { 公众: typedef Size类型大小; 尺寸R; 尺寸G; 尺寸B; 最小静态尺寸; 静态尺寸最大值; t像素(尺寸R=Min,尺寸G=Min,尺寸B=Min); }; #包括“Pixel.impl” //像素.impl 模板SizeType Pixel::Min=std::numeric_limits::Min(); 模板大小类型像素::Max=std::数值限制::Max(); 模板浮动像素::Min=0; 模板浮动像素::Max=1; 模板双像素::Min=0; 模板双像素::Max=1;
在C#中,我试图复制这一点:用C#泛型专门化一个值? 我有一些C++代码,它实现了基本的像素类。以下是我掌握的一些重要信息: // Pixel.h template <class SizeType> struct Pixel { public: typedef SizeType Size; Size R; Size G; Size B; static Size Min; static Size Max; TPixel(Size R = Min, Size G = Min, Size B = Min); }; #include "Pixel.impl" // Pixel.impl template <class SizeType> SizeType Pixel<SizeType>::Min = std::numeric_limits<Size>::min(); template <class SizeType> SizeType Pixel<SizeType>::Max = std::numeric_limits<Size>::max(); template <> float Pixel<float>::Min = 0; template <> float Pixel<float>::Max = 1; template <> double Pixel<double>::Min = 0; template <> double Pixel<double>::Max = 1; //Pixel.h 模板 结构像素 { 公众: typedef Size类型大小; 尺寸R; 尺寸G; 尺寸B; 最小静态尺寸; 静态尺寸最大值; t像素(尺寸R=Min,尺寸G=Min,尺寸B=Min); }; #包括“Pixel.impl” //像素.impl 模板SizeType Pixel::Min=std::numeric_limits::Min(); 模板大小类型像素::Max=std::数值限制::Max(); 模板浮动像素::Min=0; 模板浮动像素::Max=1; 模板双像素::Min=0; 模板双像素::Max=1;,c#,generics,C#,Generics,在C#中,我试图复制这一点: struct Pixel<Size> where Size : struct { public Size R; public Size G; public Size B; public static const Size Min; // What should I do here? public static const Size Max; } struct像素,其中大小:struct { 公共规模R; 公共规模
struct Pixel<Size> where Size : struct
{
public Size R;
public Size G;
public Size B;
public static const Size Min; // What should I do here?
public static const Size Max;
}
struct像素,其中大小:struct
{
公共规模R;
公共规模G;
公共规模B;
public static const Size Min;//我应该在这里做什么?
最大公共静态常量大小;
}
但我不知道如何将此最小/最大尺寸包含到类型中。我希望能够有一个统一的像素界面,允许你做的事情,如钳位,添加,缩放等
当我试图处理潜在任意类型的向量和矩阵时,我遇到了类似的解决方案。有人能告诉我,我能完成上面的C++代码所做的事情吗?< /p> 假设你要完成的是在C语言泛型中做模板特化,这是不可能的。 下面是一个比较两者差异的示例,但重点是:
- C#不支持显式专业化;即,特定类型模板的自定义实现
- C#不支持部分专门化:类型参数子集的自定义实现
大小添加一个接口约束,它要求大小
具有Max
和Min
方法或类似的方法。当然,在这种情况下,不再需要定义。< P>不同于C++模板特化,在.NET.</P>中没有泛型的专业化。
除非有约束,否则不能将t
实例初始化为t
,因此不能使用静态构造函数来解决问题
据我所知,没有任何约束允许您只指定数字类型或具有数字类型转换的类型
我建议你只上两种不同类型的课:
public struct PixelFloat
{
public float R { get; set; }
public float G { get; set; }
public float B { get; set; }
public const float Min = 0.0f;
public const float Max = 1.0f;
}
public struct PixelDouble
{
public double R { get; set; }
public double G { get; set; }
public double B { get; set; }
public const double Min = 0.0f;
public const double Max = 1.0f;
}
无论如何,这实际上是同一件事,因为这是它在封面下编译的内容。与此相比,其他解决方案不会为您带来太多好处,因为您仍然需要键入以下类型:Pixel
Pixel
此外,在这种情况下,我建议您使用名称,表明您正在使用泛型参数中的类型<代码>大小
显然不是通用参数<代码>TSize为。而TSize
并没有描述类型的作用,它只是描述了它是如何变化的。相反,您应该将其命名为TValue
您必须执行以下操作:
static class Pixel
{
public static Size Min<Size>() where Size : struct;
public static Size Max<Size>() where Size : struct;
}
struct Pixel<Size> where Size : struct
{
public Size R;
public Size G;
public Size B;
}
静态类像素
{
公共静态大小Min(),其中大小:struct;
public static Size Max(),其中Size:struct;
}
结构像素,其中大小:struct
{
公共规模R;
公共规模G;
公共规模B;
}
然后这样称呼它:
Pixel<double> doublePixel;
var max = Pixel.Max<double>();
像素双像素;
var max=Pixel.max();
这对你有用吗?也许是这样的吧
public struct Pixel<Size> where Size : struct
{
private enum DEF_TYPES
{
MIN,
MAX
}
private static Dictionary<Type, Dictionary<DEF_TYPES, object>> m_Defs = new Dictionary<Type, Dictionary<DEF_TYPES, object>>
{
{
typeof(float),
new Dictionary<DEF_TYPES, object> {
{DEF_TYPES.MIN, 0f},
{DEF_TYPES.MAX, 1f}
}
},
{
typeof(double),
new Dictionary<DEF_TYPES, object> {
{DEF_TYPES.MIN, 0d},
{DEF_TYPES.MAX, 1d}
}
}
};
private static Size GetValue(DEF_TYPES def_type)
{
if(!m_Defs.ContainsKey(typeof(Size)))
throw new ArgumentException("No default values for template " + typeof(Size));
if(!m_Defs[typeof(Size)].ContainsKey(def_type))
throw new ArgumentException("No default value '" + def_type + "' for template " + typeof(Size));
return (Size)m_Defs[typeof(Size)][def_type];
}
public Size R;
public Size G;
public Size B;
public static readonly Size Min = GetValue(DEF_TYPES.MIN);
public static readonly Size Max = GetValue(DEF_TYPES.MAX);
}
公共结构像素,其中大小:struct
{
私有枚举定义类型
{
闵,
马克斯
}
私有静态字典m_Defs=新字典
{
{
类型(浮动),
新词典{
{DEF_TYPES.MIN,0f},
{DEF_TYPES.MAX,1f}
}
},
{
类型(双),
新词典{
{DEF_TYPES.MIN,0d},
{DEF_TYPES.MAX,1d}
}
}
};
专用静态大小GetValue(定义类型定义类型)
{
如果(!m_Defs.ContainsKey(typeof(Size)))
抛出新ArgumentException(“模板无默认值”+typeof(大小));
如果(!m_Defs[typeof(Size)].ContainsKey(def_type))
抛出新的ArgumentException(“无默认值””+def_type+”,用于模板“+typeof(大小));
返回(大小)m_Defs[类型(大小)][定义类型];
}
公共规模R;
公共规模G;
公共规模B;
公共静态只读大小Min=GetValue(DEF_TYPES.Min);
公共静态只读大小Max=GetValue(DEF_TYPES.Max);
}
用作:
Console.WriteLine(Pixel<float>.Max);
Console.WriteLine(Pixel<float>.Min);
Console.WriteLine(Pixel<double>.Max);
Console.WriteLine(Pixel<double>.Min);
控制台写入线(像素最大值);
控制台写入线(像素最小值);
控制台写入线(像素最大值);
控制台写入线(像素最小值);
及
Pixel.Min=4;
无法编译,如预期的那样
不理想,但它可以工作。如果我读对了,你想知道如何在C#中进行模板专门化?泛型不能跨值工作,只能跨类型。如果你希望遵守Microsoft命名约定,即
Pixel
,泛型参数类型应该以大写的T开头。这里有一些指导原则:C#仍然不太适合于核心计算几何或数值分析,我希望他们将来会在这方面做得更多!您真的需要double
和float
类型吗?我认为OpenGL在float
上实现了统一。如果您做出类似的决定,它将使您的界面更加简单,并且可能会带来性能方面的好处。@Merlyin Morgan Graham-为什么不在您的答案中加入您的评论呢?:/@波利蒂:好的。这感觉好像没有直接的关系,但无论如何我会把它转移到答案中。那会有用的。有点古怪,但解决了问题,尽可能接近原始界面。
Pixel<double>.Min = 4;