What does "is { }" mean? - c#

I see the following code sometimes, and have no idea what the expression is actually testing.
public static void Something(string[] value)
{
if (value is { })
{
DoSomethingElse();
}
}

That's just the empty property pattern in C# 8, meaning the value not null. It matches any value type or reference type. As Panagiotis Kanavos notes in the comments, this is equivalent to the good old value is object check which has been in C# for a long time.
Generally if you were to specify a property, then it would match or not. This esoteric example illustrates that:
if (value is { Length: 2 })
{
// matches any object that isn't `null` and has a property set to a length of 2
}
The property patterns work best and are most clear when comparing with other patterns in cases such as switch expressions.

While Daniel's answer is right, I think it might be useful to add some context about why you may see the empty property pattern in use. Consider this example controller method that needs some validation done:
public async Task<IActionResult> Update(string id, ...)
{
if (ValidateId(id) is { } invalid)
return invalid;
...
}
In the above, ValidateId() could return null or an instance of BadObjectRequestResult. If the former is returned, the validation is successful and moves on to the rest of the body of Update. If the latter is returned, is {} is true (i.e. of course an instance of BadObjectRequestResult is an object), and the validation fails.
Nicely, out of this we've also provided a variable name, invalid, which we can return immediately. Without that we'd need slightly more verbose code.
public async Task<IActionResult> Update(string id, ...)
{
var invalid = ValidateId(id);
if (invalid != null)
return invalid;
...
}
Whether one is more readable or the other is up to the reader, I've just presented one way the empty property pattern can be used.

Related

Possibility of external functions as nullable guards?

C# 8 introduced nullable reference types, which is a very cool feature. Now if you expect to get nullable values you have to write so-called guards:
object? value = null;
if (value is null)
{
throw new ArgumentNullException();
}
…
These can be a bit repetitive. What I am wondering is if it is possible to avoid writing this type of code for every variable, but instead have a guard-type static void function that throws exception if value is null or just returns if value is not null. Or is this too hard for compiler to infer? Especially if it's external library/package?
There are a few things you can do.
You can use [DoesNotReturnIf(...)] in your guard method, to indicate that it throws if a particular condition is true or false, for example:
public static class Ensure
{
public static void True([DoesNotReturnIf(false)] bool condition)
{
if (!condition)
{
throw new Exception("!!!");
}
}
}
Then:
public void TestMethod(object? o)
{
Ensure.True(o != null);
Console.WriteLine(o.ToString()); // No warning
}
This works because:
[DoesNotReturnIf(bool)]: Placed on a bool parameter. Code after the call is unreachable if the parameter has the specified bool value
Alternatively, you can declare a guard method like this:
public static class Ensure
{
public static void NotNull([NotNull] object? o)
{
if (o is null)
{
throw new Exception("!!!");
}
}
}
And use it like this:
public void TestMethod(object? o)
{
Ensure.NotNull(o);
Console.WriteLine(o.ToString()); // No warning
}
This works because:
[NotNull]: For outputs (ref/out parameters, return values), the output will not be null, even if the type allows it. For inputs (by-value/in parameters) the value passed is known not to be null when we return.
SharpLab with examples
Of course, the real question is why you want to do this. If you don't expect value to be null, then declare it as object?, rather than object -- that's the point of having NRTs.
There is a Guard Clauses library by Steve Ardalis that I think can help you with this situation.
You can do things like:
Guard.Against.Null (throws if input is null)
Guard.Against.NullOrEmpty (throws if string or array input is null or empty)
Guard.Against.NullOrWhiteSpace (throws if string input is null, empty or whitespace)
Guard.Against.OutOfRange (throws if integer/DateTime/enum input is outside a provided range)
Guard.Against.OutOfSQLDateRange (throws if DateTime input is outside the valid range of SQL Server DateTime values)
Guard.Against.Zero (throws if number input is zero)
In this blog post Jason Roberts made a quick explanation of the library too.
There is another Guard Class in the Microsoft.Toolkit.Diagnostics namespace but probably is not viable in all the use cases that will depend if wanna add that dependency to the project or not.

Assigning default values to parameters when passed a NULL

Is there a better way of doing this -
if (Number.IsNotNullOrEmpty())
{
var status = _Logic.Order(data, Number);
}
else
{
var status = _Logic.Order(data);
}
Signature of the Order method -
Order(Data data, string number = "4a")
I am basically calling the same method in a different way based on if the number is NULL.
Since null is a valid value to be passed to a method, methods will typically have to deal with the possibility themselves that an argument may be null. Usually, you will see something like this then:
public void Example(string arg)
{
if (arg == null)
throw new ArgumentNullException(nameof(arg));
// …
}
That is for the case where passing a null value is not supported. But there is nothign wrong with explicitly allowing a null value to be passed and handling that internally. For example, instead of throwing an exception, you could simply assign a fallback value:
public void Example(string arg)
{
if (arg == null)
arg = "some default";
// …
}
If you cannot modify your method to add such a logic, then you will have to deal with this outside. If you do know the fallback value yourself, then you can simply use one of these many ways:
// null-coalescing operator
_logic.Order(data, number ?? "4a");
// ternary conditional operator
_logic.Order(data, number != null ? number : "4a" );
// adjust the value separately first
if (number == null)
number = "4a";
_logic.Order(data, number);
If you do not know the default value but instead have to rely on the default value that the method signature offers, or if you have to call a separate overload instead (where the second parameter is not used), then you will unfortunately have to use two separate calls for this. So you won’t be able to avoid this:
if (number != null)
_logic.Order(data, number);
else
_logic.Order(data);
Btw. of course, when dealing with strings, sometimes it makes more sense to use string.IsNullOrEmpty instead of a strict null check. I’ve kept this a strict null check to show the general idea. You can of course adjust it as necessary.
If you don't have control over the signature of Order, a simplified way to write your code from the caller's perspective would be to either use the ?? null-coalescing operator:
var status = _Logic.Order(data, Number ?? "4a");
But that only checks for null, so if you want to check for empty as well, you can do:
var status = _Logic.Order(data, string.IsNullOrEmpty(Number) ? "4a" : Number);
But if you do have control over the method, then rather than have an optional parameter (which can cause some problems down the line if modified), another option is to provide different overloads for the method:
public static void Order (Data data)
{
Order(data, "4a");
}
public static void Order (Data data, string number)
{
// Do stuff here
}
Of course this still doesn't prevent someone from passing null in the number field, so at some point you'll have to do some argument validation. This is pretty common in most methods:
public static void Order (Data data, string number)
{
if (data == null) throw new ArgumentNullException(nameof(data));
if (string.IsNullOrEmpty(number)) number = "4a";
// Do stuff here
}
You can use the following solution to assign default values to parameters when passed NULL:
public static void Order (Data data, string number=null)
{
// Do stuff here
}
Assuming you can't refactor the Logic class for some reason, but you need to use its default, you could maybe use this pattern:
_Logic.Order(data, Number.IsNotNullOrEmpty ? Number : DefaultForNumber.Value);
But the implementation for DefaultForNumber is kind of a pain.
static Lazy<string> DefaultForNumber = new Lazy<string>
(
() => typeof(Logic).GetMethod("Order").GetParameters()[1].DefaultValue as string
);

SSIS Transformation: Why do I get Object not set to instance error, unless row wrapped in conditional statement

I am accessing a text/flat file via flat file source: In the Transformation Task I have the Input Column as ZipCode and the Output Alias as: ZipCode. Usage Type: Read/Write:
I created an Ouput Column; tBookName.
The code looks like this:
This is simply an example of the behavior I have observed.
This mostly happens when I try to use certain methods like Trim( or length.
//This gives me an error message:
//Object Not set to instance Of an object
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string zipCode = (Row.ZipCode.Trim().lenght != 5 ? null : Row.ZipCode.Trim());
}
//This works:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
if (!string.IsNullOrEmpty(Row.ZipCode))
{
string zipCode = (Row.ZipCode.Trim().lenght != 5 ? null : Row.ZipCode);
}
}
If you explore the autogenerated code, you'll see that ZipCode is not a primitive type, string. Instead it's a complex type/object because the base types don't support nulls, well not gracefully at least.
Instead, what they have chosen to do is to create a simple object that exposes an _IsNull extension/method/something to allow you to test for whether the type is null.
A more idiomatic way of writing your test would be (excluding the fact that I'm not testing for empty). You have a slightly special case since the string types have the isnullorempty and isnullorwhitespace methods to check for this. If you had other primitives to deal with, then you'd become very familiar with the _IsNull check.
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
if (!Row.ZipCode_IsNull))
{
string zipCode = (Row.ZipCode.Trim().length != 5 ? null : Row.ZipCode);
}
}
Sorry to all the .NET developers out there. My terminology is probably horrible dated. Feel free to edit this answer while I go sort my punch cards.

Objects with many value checks c#

I want to see your ideas on a efficient way to check values of a newly serialized object.
Example I have an xml document I have serialized into an object, now I want to do value checks. First and most basic idea I can think of is to use nested if statments and checks each property, could be from one value checking that it has he correct url format, to checking another proprieties value that is a date but making sue it is in the correct range etc.
So my question is how would people do checks on all values in an object? Type checks are not important as this is already taken care of it is more to do with the value itself. It needs to be for quite large objects this is why I did not really want to use nested if statements.
Edit:
I want to achieve complete value validation on all properties in a given object.
I want to check the value it self not that it is null. I want to check the value for specific things if i have, an object with many properties one is of type string and named homepage.
I want to be able to check that the string in the in the correct URL format if not fail. This is just one example in the same object I could check that a date is in a given range if any are not I will return false or some form of fail.
I am using c# .net 4.
Try to use Fluent Validation, it is separation of concerns and configure validation out of your object
public class Validator<T>
{
List<Func<T,bool>> _verifiers = new List<Func<T, bool>>();
public void AddPropertyValidator(Func<T, bool> propValidator)
{
_verifiers.Add(propValidator);
}
public bool IsValid(T objectToValidate)
{
try {
return _verifiers.All(pv => pv(objectToValidate));
} catch(Exception) {
return false;
}
}
}
class ExampleObject {
public string Name {get; set;}
public int BirthYear { get;set;}
}
public static void Main(string[] args)
{
var validator = new Validator<ExampleObject>();
validator.AddPropertyValidator(o => !string.IsNullOrEmpty(o.Name));
validator.AddPropertyValidator(o => o.BirthYear > 1900 && o.BirthYear < DateTime.Now.Year );
validator.AddPropertyValidator(o => o.Name.Length > 3);
validator.Validate(new ExampleObject());
}
I suggest using Automapper with a ValueResolver. You can deserialize the XML into an object in a very elegant way using autommaper and check if the values you get are valid with a ValueResolver.
You can use a base ValueResolver that check for Nulls or invalid casts, and some CustomResolver's that check if the Values you get are correct.
It might not be exacly what you are looking for, but I think it's an elegant way to do it.
Check this out here: http://dannydouglass.com/2010/11/06/simplify-using-xml-data-with-automapper-and-linqtoxml
In functional languages, such as Haskell, your problem could be solved with the Maybe-monad:
The Maybe monad embodies the strategy of combining a chain of
computations that may each return Nothing by ending the chain early if
any step produces Nothing as output. It is useful when a computation
entails a sequence of steps that depend on one another, and in which
some steps may fail to return a value.
Replace Nothing with null, and the same thing applies for C#.
There are several ways to try and solve the problem, none of them are particularly pretty. If you want a runtime-validation that something is not null, you could use an AOP framework to inject null-checking code into your type. Otherwise you would really have to end up doing nested if checks for null, which is not only ugly, it will probably violate the Law of Demeter.
As a compromise, you could use a Maybe-monad like set of extension methods, which would allow you to query the object, and choose what to do in case one of the properties is null.
Have a look at this article by Dmitri Nesteruk: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
Hope that helps.
I assume your question is: How do I efficiently check whether my object is valid?
If so, it does not matter that your object was just deserialized from some text source. If your question regards checking the object while deserializing to quickly stop deserializing if an error is found, that is another issue and you should update your question.
Validating an object efficiently is not often discussed when it comes to C# and administrative tools. The reason is that it is very quick no matter how you do it. It is more common to discuss how to do the checks in a manner that is easy to read and easily maintained.
Since your question is about efficiency, here are some ideas:
If you have a huge number of objects to be checked and performance is of key importance, you might want to change your objects into arrays of data so that they can be checked in a consistent manner. Example:
Instead of having MyObject[] MyObjects where MyObject has a lot of properties, break out each property and put them into an array like this:
int[] MyFirstProperties
float[] MySecondProperties
This way, the loop that traverses the list and checks the values, can be as quick as possible and you will not have many cache misses in the CPU cache, since you loop forward in the memory. Just be sure to use regular arrays or lists that are not implemented as linked lists, since that is likely to generate a lot of cache misses.
If you do not want to break up your objects into arrays of properties, it seems that top speed is not of interest but almost top speed. Then, your best bet is to keep your objects in a serial array and do:
.
bool wasOk = true;
foreach (MyObject obj in MyObjects)
{
if (obj.MyFirstProperty == someBadValue)
{
wasOk = false;
break;
}
if (obj.MySecondProperty == someOtherBadValue)
{
wasOk = false;
break;
}
}
This checks whether all your objects' properties are ok. I am not sure what your case really is but I think you get the point. Speed is already great when it comes to just checking properties of an object.
If you do string compares, make sure that you use x = y where possible, instead of using more sophisticated string compares, since x = y has a few quick opt outs, like if any of them is null, return, if the memory address is the same, the strings are equal and a few more clever things if I remember correctly. For any Java guy reading this, do not do this in Java!!! It will work sometimes but not always.
If I did not answer your question, you need to improve your question.
I'm not certain I understand the depth of your question but, wouldn't you just do somthing like this,
public SomeClass
{
private const string UrlValidatorRegex = "http://...
private const DateTime MinValidSomeDate = ...
private const DateTime MaxValidSomeDate = ...
public string SomeUrl { get; set; }
public DateTime SomeDate { get; set; }
...
private ValidationResult ValidateProperties()
{
var urlValidator = new RegEx(urlValidatorRegex);
if (!urlValidator.IsMatch(this.Someurl))
{
return new ValidationResult
{
IsValid = false,
Message = "SomeUrl format invalid."
};
}
if (this.SomeDate < MinValidSomeDate
|| this.SomeDate > MinValidSomeDate)
{
return new ValidationResult
{
IsValid = false,
Message = "SomeDate outside permitted bounds."
};
}
...
// Check other fields and properties here, return false on failure.
...
return new ValidationResult
{
IsValid = true,
};
}
...
private struct ValidationResult
{
public bool IsValid;
public string Message;
}
}
The exact valdiation code would vary depending on how you would like your class to work, no? Consider a property of a familar type,
public string SomeString { get; set; }
What are the valid values for this property. Both null and string.Empty may or may not be valid depending on the Class adorned with the property. There may be maximal length that should be allowed but, these details would vary by implementation.
If any suggested answer is more complicated than code above without offering an increase in performance or functionality, can it be more efficient?
Is your question actually, how can I check the values on an object without having to write much code?

How to tell if an out parameter was set already?

Is there a way to know if an out parameter was set already or not. This is the pseudocode for what I am looking for:
public virtual string blabla(long num, out bool bval)
{
if (!bval.HasValue)
{
//Do some default logic
bval = defaultValue;
}
return blabla2(num, bval);
}
You can't - you can't read the variable until it's been definitely assigned within your method. You should think of it as being like a local variable, declared but not assigned any value at the start of the method - but which you must assign a value to before you return. (It's okay not to have assigned a value to it if an exception is thrown.)
If you want a parameter which carries information as input to the method as well as propagating information out, you should use ref instead of out.
See my article on parameter passing for more information.
In addition to Jon's excellent answer, if you want the parameter to still be out, but need to see if it has been assigned a value at some place inside the method, you could use a local nullable type like follows:
public virtual string blabla(long num, out bool bval)
{
bool? bvalLocal;
... //I'm assuming there is some code here that may or
//may not assign bvalLocal?
// This whole if block may not be needed if the default
// value is the default for the type (i.e. false) as
// GetValueOrDefualt() will take care of that (see
// second to last line).
if (!bvalLocal.HasValue)
{
//Do some default logic
bvalLocal = defaultValue;
}
bval = bvalLocal.GetValueOrDefault();
return blabla2(num, bval);
}

Categories