C#中的新类型定义

mny*_*rar 11 c# types

我正在寻找定义新类型并在C#中使用它的可能性,如下所示:

班级定义:

public class Position
{
    public double180 Longitude { get; set; } // double180 is a type within a range -180 and 180
    public double90 Latitude { get; set; } // double90 is a type within a range of -90 and 90
}
Run Code Online (Sandbox Code Playgroud)

用法:

var position = new Position
{
     Longitude = 45,
     Latitude = 96 // This line should give an error while initializing the object
};
Run Code Online (Sandbox Code Playgroud)

Typ*_*eIA 11

您不一定需要新类型.您可以手动编写用于验证值的setter,而不是使用auto属性:

public double Latitude
{
    get
    {
        return mLatitude;
    }

    set
    {
        if (value > 90 || value < -90)
        {
            throw new ArgumentOutOfRangeException("Invalid latitude");
        }

        mLatitude = value;
    }
}

private double mLatitude;
Run Code Online (Sandbox Code Playgroud)

如果要重用此代码,可以定义自己的类型并在其中使用上面的setter; 然后提供适当的构造函数和转换运算符.


Fra*_*nkO 7

您最好添加System.ComponentModel.DataAnnotations并使用[Range],如下所示:

public class Position
{
    [Range(-180, 180)]
    public double Longitude { get; set; }

    [Range(-90, 90)]
    public double Latitude { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • @FrankO当然,但这仍然只是*咨询*验证,由调用者而不是被调用者强制执行. (2认同)

Kri*_*ten 7

一个类型可能有点过分,但如果你想要一个类型,这是一个好的开始:

struct Double180 : IEquatable<Double180>
{
    private readonly double value;

    public Double180(double d)
    {
        if (d < -180 || d > 180)
        {
            throw new ArgumentOutOfRangeException("d");
        }

        this.value = d;
    }

    public static implicit operator double(Double180 d)
    {
        return d.value;
    }

    public static explicit operator Double180(double d)
    {
        return new Double180(d);
    }

    public override string ToString()
    {
        return this.value.ToString();
    }

    public bool Equals(Double180 other)
    {
        return this.value == other.value;
    }

    public override bool Equals(object obj)
    {
        return obj is Double180 && this.Equals((Double180)obj);
    }

    public override int GetHashCode()
    {
        return this.value.GetHashCode();
    }

    public static bool operator ==(Double180 a, Double180 b)
    {
        return a.Equals(b);
    }

    public static bool operator !=(Double180 a, Double180 b)
    {
        return !a.Equals(b);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,还有更多的接口要实现,例如IConvertible并且IComparable<Double180>会很好.

如您所见,您知道它从何处开始,但您不知道它的结束位置.

如其他答案所示,setter验证器可能是更好的主意.


Dav*_*ych 5

使用 adouble并让 setter 检查值:

private double _longitude;
public double Longitude
{
    get
    {
        return _longitude;
    }
    set
    {
        if(value < -180 || value > 180)
        {
            throw new ArgumentException("value");
        }
        _longitude = value;
    }
}
Run Code Online (Sandbox Code Playgroud)