用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++代码,它实现了基本的像素类。以下是我掌握的一些重要信息: // 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; 公共规模

在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;
公共规模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;