简体   繁体   English

具有泛型的可空基元

[英]Nullable primitives with Generics

I'm trying to find the right thing to do with a non-null validation on a nullable boolean. 我试图找到对可空布尔值进行非空验证的正确方法。 I also want to be able to do the same thing with some other fields, including strings, ints, etc., so I want to use generics for the method. 我还希望能够对其他一些字段执行相同的操作,包括字符串,整数等,因此我想对该方法使用泛型。 Here's an example of the kind of thing which can happen. 这是可能发生的事情的一个示例。

bool? myValue = null;
bool valid = ValidateNotNull(myValue);

And here's some validation code: 这是一些验证代码:

public bool ValidateNotNull<T>(T nullableField)
{
    return nullableField != null;
}

All the answers I've found to this kind of problem suggest adding a where T : struct or where T: class to the method signature, or using default(T) in the comparison, none of which will work for a bool where false is a valid value. 我发现的所有此类问题的答案都建议在方法签名中添加where T : structwhere T: class ,或在比较中使用default(T) ,对于布尔false的布尔值,这些都不起作用有效值。

Any other suggestions? 还有其他建议吗? The code compiles, but Resharper isn't happy about that null comparison on a value which it thinks might be a primitive, and I'd love to know what I should be doing to cheer it up. 代码可以编译,但是Resharper对它认为可能是原始值的空值比较不满意,我很想知道我应该做些什么来振作起来。

NB: This isn't the complete code. 注意:这不是完整的代码。 I'm still interested in maintaining the type. 我仍然对保持类型感兴趣。 This is also not the only place I've run into the problem. 这也不是我遇到问题的唯一地方。

NB2: Yes, it compiles and works fine. NB2:是的,它可以编译并正常工作。 What I really want to know is whether there is a code solution for stopping Resharper from complaining, or an idiomatic way to do this which I don't know about. 我真正想知道的是是否存在阻止Resharper抱怨的代码解决方案,或者是我不知道的惯用方式来做到这一点。

The code below will validate nullable types and reference types: 以下代码将验证可为空的类型和引用类型:

 public bool ValidateNotNull<T>(Nullable<T> nullableField) where T:struct
 {
  return nullableField.HasValue;
 }

 public bool ValidateNotNull<T>(T nullableField) where T:class
 {
  return nullableField!=null;
 }

Would comparing to default work? 将与默认工作进行比较吗?

  public bool ValidateNotNull<T>(T nullableField) { return Equals(nullableField, default(T)); } 

Updated: 更新:

Either its a primitive , and all is well, or its not null: 它是一个原始类型 ,或者一切都很好,或者它不是null:

    public bool ValidateNotNull<T>(T nullableField)
    {
        return typeof(T).IsPrimitive || !Equals(nullableField, null);
    }

I also want to be able to do the same thing with some other fields, including strings, ints, etc 我还希望能够对其他一些字段执行相同的操作,包括字符串,整数等

OK, so you want a method that can be passed either a Nullable<> (which is a struct ), or a reference type, and will return true iff the argument is null (note that your name appears to be the wrong way round, but there you go). 好的,因此您想要一个可以传递Nullable<> (它是struct )或引用类型的方法,并且如果参数为null将返回true (请注意,您的名字似乎是错误的方式,但你去了)。

The thing is, if that's all this method has to do, then you don't need generics because you don't need type-safety. 关键是,如果这是该方法所要做的全部 ,那么您就不需要泛型,因为您不需要类型安全。 This example works and does what you want, I think: 我认为这个示例可以工作并满足您的要求:

class Program
{
    static void Main(string[] args)
    {
        int? x = null;
        int? y = 5;
        string s = null;
        string r = "moo";

        Console.WriteLine(ValidateNotNull(x));
        Console.WriteLine(ValidateNotNull(y));
        Console.WriteLine(ValidateNotNull(s));
        Console.WriteLine(ValidateNotNull(r));

        Console.ReadLine();

    }

    private static bool ValidateNotNull(object o)
    {
        return o == null;
    }
}

This outputs 这个输出

True
False
True
False

which is I believe your required output. 我相信这是您所需的输出。

I don't know why you thing your method doesn't work (apart from using != rather than == ), because as far as I can tell, it already works! 我不知道为什么您的方法不起作用(除了使用!=而不是== ),因为据我所知,它已经起作用了! You can compare any value of type T with null (when T is a generic type parameter). 您可以将T类型的任何值与null进行比较(当T是通用类型参数时)。 If a non-nullable value type is used for T, the result will be treated as a constant ( false for == null , true for != null ). 如果T使用非空值类型,则结果将被视为常量(对于== null ,为false ;对于!= null ,为true )。

So, this should be fine. 因此,这应该很好。

public bool ValidateNotNull<T>(T nullableField)
{
    return nullableField != null;
}

But this would also work without generics: 但这也可以在没有泛型的情况下工作:

public bool ValidateNotNull(object nullableField)
{
    return nullableField != null;
}

(Because boxing a Nullable<T> null value returns a null reference.) (因为装箱Nullable<T> null值将返回空引用。)

You need to use 您需要使用

public bool ValidateNotNull<T>(T nullableField)
{
    return nullableField.HasValue;
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM