c#从int32派生

sec*_*ond 16 c#

我有几个成员叫做'Id'.本来我想把这些作为整体存储,但我想要一些保护层,以确保我不会意外地为一个人等分配房间ID.

一个解决方案是typedef(使用RoomId = System.Int32;)然后我需要使用这些代码在所有文件中.我更喜欢例如从int32派生的RoomId类,但我无法弄清楚如何设置它以允许显式转换(用于初始化)

或者我应该以其他方式这样做?

Luk*_*keH 34

您无法派生Int32,但您可以指定隐式转换,这可能会为您提供所需的行为:

public struct RoomId
{
    private int _Value;

    public static implicit operator RoomId(int value)
    {
        return new RoomId { _Value = value };
    }

    public static implicit operator int(RoomId value)
    {
        return value._Value;
    }
}

// ...

RoomId id = 42;

Console.WriteLine(id == 41);    // False
Console.WriteLine(id == 42);    // True
Console.WriteLine(id < 42);     // False
Console.WriteLine(id > 41);     // True
Console.WriteLine(id * 2);      // 84
Run Code Online (Sandbox Code Playgroud)

  • 尽管这看起来很酷,但实际上,隐式大小写会损害静态类型的安全性。强制重载使您可以将int赋值(或传递参数),但这实际上不是您想要的。您不希望它自动“像int一样工作”,因为那样您可能会将它传递到错误的位置。只有实际需要内部int的最低级别的代码才可以访问它,并强迫它调用显式方法或属性(如Value)将提供更高级别的类型安全性。 (2认同)

Meh*_*ari 9

 public static explicit operator RoomId(int value) {
     return new RoomId { Id = value };
 }
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

 RoomId variable = (RoomId)10;
Run Code Online (Sandbox Code Playgroud)

Int32在C#中无法从类或任何其他值类型派生类.


Tam*_*ege 7

如果我理解正确,你真正需要的唯一操作就是平等比较.您可以创建一个RoomId类(或结构,适合您)

class RoomId
{
    private int Value {get; set;}

    public RoomId(int value)
    {
        this.Value = value;
    }

    public bool Equals(RoomId other)
    {
        return this.Value == other.Value;
    }
}

RoomId room1 = new RoomId(1);
RoomId room2 = new RoomId(2);

// To compare for equality
bool isItTheSameRoom = room1.Equals(room2);
// Or if you have overloaded the equality operator (==)
bool isItTheSameRoom = room1 == room2;
Run Code Online (Sandbox Code Playgroud)

您可以实现IEquatable,如果需要,可以重载相等和不等运算符.如果需要持久性,可以实现ISerializable接口,以确保整数值仅在实际需要时"转义"类.