-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Attribute to Specify Return Value Effect on Related Property/Field Non-Nullability #3102
Comments
Yes, this comes up in Roslyn apis as well. For example Seems reasonably common to have some some property available that allows you to know when somethin else will/won't be null. |
I seem to recall this being raised somewhere for |
This would allow for a dead-simple safe implementation of an public struct Option<T>
{
public readonly bool HasValue;
[NotNullWhen(nameof(HasValue), true)]
public readonly T Value;
public Option<T>(T value) => (HasValue, Value) = (true, value);
// equality and friends omitted
} Is this sort of functionality on the roadmap? |
That |
Hmmm you're right. The "pure" implementation of Something along the lines of... public class Test
{
public int A;
public int? B;
public string C;
public string? D;
} Each of these members would have an uninitialized error/warning, and so you'd have to initialize them in the constructor. It would still let you initialize them to null or default or whatever you want. This would be basically identical to how the null context works, except it wouldn't care about the types since it's concerned with initialization. This is definitely a bit too complicated to even propose though, especially given how complicated the null context stuff already is, and this wouldn't even be able to replace that since initialization does not affect nullability. Not to mention that initialization can be a little hard to pin down in every scenario (just like nullability is proving to be). I suppose an impure implementation of |
Actually, even if you coerced null values to |
@SirUppyPancakes public bool HasValue([MaybeNullWhen(false)] out T value) I've been using this in my own version of |
Yeah that's definitely the cleanest approach at the moment, though there is still the problem of handling value types: Option<int> x = new Option<int>(123);
if (x.HasValue(out int value))
{
// accessing value here has no warning
}
{
// accessing value here has no warning, but would be nice if it warned
} If the default context attributes and flow analysis is introduced, it would warn in the else block. Having a |
That's true, but as you already noted, that requires 146 and Defaultable analysis (which hopefully isn't too hard to piggy-back off of the compiler's infrastructure for NRT analysis). |
You can also close the gap with a custom analyzer if you're willing to put in 1000x the effort compared to carrying around a code snippet. |
Nevermind, I shouldn't be posting before coffee. |
Closing as now implemented in C# 9 using e.g. public class CollectionOfStuff
{
private Stuff[]? _stuff;
[MemberNotNullWhen(false, nameof(_stuff))]
public bool IsEmpty => _stuff == null || _stuff.Length == 0;
public void DoSomething()
{
if (!IsEmpty)
Array.Reverse(_stuff); // Don't warn that _stuff may be null
}
} |
I've found myself running into this a few times as I port my libs to NRTs. It would be useful to be able to specify that a particular property or method return value means that a related property or field will not be null. It could be marked in either "direction" and the second example is probably easier to implement in the NRT flow analyzer, though the first example reads much nicer to me and can be implemented with overloaded constructors on the existing attributes:
This should/could also work for fields:
I played around with various ways to name the
[IndicatesNotNullWhen]
annotation and arrange the parameters but I couldn't really come up with something that felt right. That said, both annotations could be useful since the[IndicatesNotNullWhen]
variation could be used on return values of methods as well:The text was updated successfully, but these errors were encountered: