如何创建像任何其他通用数据类型一样支持算术运算的自定义数据类型
How to create a custom data type that supports arithmetic operations as any other generic data type
我正在尝试创建一个新类型 UInt24。为此,我使用了一个结构(欢迎提出更好的建议)。
虽然我现在可以将变量转换为这个新定义的类型,但我无法支持泛型算术。
我用显式和隐式运算符尝试了很多东西,但我真的不明白它是如何工作的。
这是我拥有的:
namespace MySytem
{
public struct UInt24
{
internal uint m_value;
public static explicit operator UInt24(uint v) => new UInt24(v);
public const uint MaxValue = (uint)0xFFFFFF;
public const short MinValue = unchecked((short)0x000000);
public UInt24(uint v)
{
if (v > MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(v), $"Value too big - Max is {MaxValue}.");
}
if (v < MinValue)
{
throw new ArgumentOutOfRangeException(nameof(v), $"Value too small - Min is {MinValue}.");
}
this.m_value = v;
}
}
}
现在,这让我可以做这样的事情:
UInt24 a = (UInt24)0x123456;
但我希望能够做到这一点:
UInt24 a = (UInt24)0x123456;
a++; // Not working
a--; // Not working
a = a + 1 // Not working
此外,有没有一种方法可以声明一个 UInt24 变量而不必强制转换数字?
而不是:
UInt24 a = (UInt24)0x123456;
我们能否让它直接工作:
UInt24 a = 0x123456; // No casting needed
您可以隐式定义运算符:
public static implicit operator UInt24(uint v) { return new UInt24(v); }
您需要实现 +、-、++ 和 -- 运算符:
public static UInt24 operator +(UInt24 u1, UInt24 u2) { return u1.m_value + u2.m_value; }
public static UInt24 operator -(UInt24 u1, UInt24 u2) { return u1.m_value - u2.m_value; }
public static UInt24 operator ++(UInt24 u1) { return u1.m_value + 1; }
public static UInt24 operator --(UInt24 u1) { return u1.m_value - 1; }
然后可以执行算术运算:
UInt24 u24_1 = 0x000001;
UInt24 u24_2 = u24_1 + 0x000001;
u24_1++;
u24_2--;
Console.WriteLine("{0}", u24_1);
Console.WriteLine("{0}", u24_2);
还建议覆盖 ToString():
public override string ToString()
{
return m_value.ToString();
}
结果是,
2
1
我正在尝试创建一个新类型 UInt24。为此,我使用了一个结构(欢迎提出更好的建议)。
虽然我现在可以将变量转换为这个新定义的类型,但我无法支持泛型算术。
我用显式和隐式运算符尝试了很多东西,但我真的不明白它是如何工作的。
这是我拥有的:
namespace MySytem
{
public struct UInt24
{
internal uint m_value;
public static explicit operator UInt24(uint v) => new UInt24(v);
public const uint MaxValue = (uint)0xFFFFFF;
public const short MinValue = unchecked((short)0x000000);
public UInt24(uint v)
{
if (v > MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(v), $"Value too big - Max is {MaxValue}.");
}
if (v < MinValue)
{
throw new ArgumentOutOfRangeException(nameof(v), $"Value too small - Min is {MinValue}.");
}
this.m_value = v;
}
}
}
现在,这让我可以做这样的事情:
UInt24 a = (UInt24)0x123456;
但我希望能够做到这一点:
UInt24 a = (UInt24)0x123456;
a++; // Not working
a--; // Not working
a = a + 1 // Not working
此外,有没有一种方法可以声明一个 UInt24 变量而不必强制转换数字? 而不是:
UInt24 a = (UInt24)0x123456;
我们能否让它直接工作:
UInt24 a = 0x123456; // No casting needed
您可以隐式定义运算符:
public static implicit operator UInt24(uint v) { return new UInt24(v); }
您需要实现 +、-、++ 和 -- 运算符:
public static UInt24 operator +(UInt24 u1, UInt24 u2) { return u1.m_value + u2.m_value; }
public static UInt24 operator -(UInt24 u1, UInt24 u2) { return u1.m_value - u2.m_value; }
public static UInt24 operator ++(UInt24 u1) { return u1.m_value + 1; }
public static UInt24 operator --(UInt24 u1) { return u1.m_value - 1; }
然后可以执行算术运算:
UInt24 u24_1 = 0x000001;
UInt24 u24_2 = u24_1 + 0x000001;
u24_1++;
u24_2--;
Console.WriteLine("{0}", u24_1);
Console.WriteLine("{0}", u24_2);
还建议覆盖 ToString():
public override string ToString()
{
return m_value.ToString();
}
结果是,
2
1