从Nullable隐式转换为正常,任何想法?

时间:2011-04-25 22:49:03

标签: c# nullable implicit-conversion

我想知道如何隐式转换为可空的“?”区域变量。

给出这个例子

int? x = 5;

int y = x; //this gonna fail, !!!

我需要某种方法来覆盖=参数,但不幸的是= =参数不可重载......任何建议

我正在使用C#

4 个答案:

答案 0 :(得分:12)

您有两个选项,直接访问该值(如果您确定它不为空):

int y = x.Value;

或者,使用null合并运算符:

int y = x ?? 0; // 0 if null...

答案 1 :(得分:7)

可以实现implicit cast operator,但只能实现您定义的类型。例如,做这样的事情..

public class NullableExtensions 
{
    public static implicit operator int(int? value)
    {
        return value ?? default(int);
    }
}

..将返回CS0556编译错误,因为强制转换不包含用户定义的类型。

你最接近的是定义你自己的Nullable类型,它确实包含一个隐式的强制转换操作符:

public struct ImplicitNullable<T> where T: struct
{
    public bool HasValue { get { return this._value.HasValue; } }
    public T Value { get { return this._value.Value; } }

    public ImplicitNullable(T value) : this() { this._value = value; }
    public ImplicitNullable(Nullable<T> value) : this() { this._value = value; }

    public static implicit operator ImplicitNullable<T>(T value) { return new ImplicitNullable<T>(value); }
    public static implicit operator ImplicitNullable<T>(Nullable<T> value) { return new ImplicitNullable<T>(value); }

    public static implicit operator T(ImplicitNullable<T> value) { return value._value ?? default(T); }
    public static implicit operator Nullable<T>(ImplicitNullable<T> value) { return value._value; }

    private Nullable<T> _value { get; set; }

    // Should define other Nullable<T> members, especially 
    // Equals and GetHashCode to avoid boxing
}

请注意,虽然可以编写此代码,但可能会导致难以跟踪错误。我建议使用显式强制转换,或者当值为null时抛出异常。

之后,您可以按照预期进行投射:

static void Main()
{
    int myInt = 1;
    int? nullableInt = 2;

    ImplicitNullable<int> implicitInt;

    // Convert from int or int?
    implicitInt = myInt;
    implicitInt = nullableInt;

    // Convert to int or int?
    myInt = implicitInt;
    nullableInt = implicitInt;
}

答案 2 :(得分:3)

等等,我很困惑......

为什么不使用GetValueOrDefault

答案 3 :(得分:1)

我假设这是C#

您需要投射或使用.value

 int? x = 5;
 int y;

 if(x.HasValue)
     y = x.Value;
 else
     throw new//... handle error or something