Well, I have the following query that I use to search a LIST with the text that the user has filled.
It's only one textbox that search in all these fields below, it's working but when one of these fields is null, it's throwing a null reference exception, how can I avoid that?
List<REP_MEDIDORDISPLAY> SearchFiltered = new List<REP_MEDIDORDISPLAY>();
if (filter != String.Empty)
{
SearchFiltered.Clear();
foreach (String Item in filter.Split(';').ToList<String>())
{
SearchFiltered.AddRange(Medidores.Where(x => x.Data_TOI.Contains(Item.Trim()) ||
x.Elemento.ToUpper().Contains(Item.Trim()) ||
x.Fase.ToUpper().Contains(Item.Trim()) ||
x.ID.ToUpper().Contains(Item.Trim()) ||
x.KdKe.ToUpper().Contains(Item.Trim()) ||
x.N_Equipamento.ToUpper().Contains(Item.Trim()) ||
x.Status.ToUpper().Contains(Item.Trim()) ||
x.Tensao.ToUpper().Contains(Item.Trim())));
}
}
I hope you guys can help me. thanks.
By checking for null first:
(x.Elemento != null && x.Elemento.ToUpper().Contains(Item.Trim())) ||
// etc
Of course you should also calculate Item.Trim() just once and reuse this value for all tests rather than trimming as many times as there are fields.
You can add null check to each of the properties. Example:
From
x.Fase.ToUpper().Contains(Item.Trim()) ||
To
(x.Fase != null && x.Fase.ToUpper().Contains(Item.Trim())) ||
Maybe you should introduce something like a null object. This object is empty and will therefore always return false on every query against it.
If you implement nullchecks for every property on that object your code will rot over time. And you are gonna have a bad time.
There are many ways to do what you are doing, some more elegant perhaps.
One simple way could be to override the ToString method in the object in the Medidores sequence and use that for the comparison.
Something like this:
class Medidor {
... properties
public override string ToString() {
return Data_TOI + Elemento ... etc
}
}
And then you could compare against that instead.
SearchFiltered.AddRange(
Medidores.Where(x =>
x.ToString()
.IndexOf(Item.Trim(), 0, StringComparison.InvariantCultureIgnoreCase) != -1
);
I'm using IndexOf as it has an overload that takes StringComparison.InvariantCultureIgnoreCase, which ignores casing among other things.
The reason why I think this approach is preferred to what you have now, is that the Meridor object itself is responsible for what fields are included in the ToString method. Maybe it can improve readability and maintainability.
Related
I Have a method to get all Ticket with filtering by FromDate .
my code like this :
public List<Model.Ticket> SelectList(DateTime? fromDate = null)
{
db.Tickets.Where(row=> (!fromDate.HasValue || (fromDate.HasValue ? (row.Date.Date >= fromDate.Value.Date) : false));
}
but when pass null It returns an exception :
Nullable object must have a value.
what's wrong?
You need to get all Ticket with filtering by FromDate, But in your where condition will only return true or false acording to the formdate you are passing as a parameter.But where condition expect a logic to filter data from the table acording to.You have to modify your where condition as
where(ticket=>ticket.formDate--here what ever the condition you need to apply)
NB: For your lambda expression(
db.Tickets.Where(!fromDate.HasValue || (fromDate.HasValue ? (row.Date.Date >= fromDate.Value.Date) : false))
)
the db query will be
select * from Tickets where true/false--acording to the output
this won't work
Maybe in your object declaration you have to initialize it
Null to be initialized by using new keyword. As directly assigning null to certain object doesn't carry desired contents. Debugging still shows value to null but it can't be instantiated likewise.
I've got an object, specifically the following:
table.ExtendedProperties["MS_Description"].Value
If there is not property, the Value is null. If there is a property, but it is empty, the Value.toString() is "".
I would thus like to create an if-statement which caters for both eventualities. This is what I've done so far:
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value.ToString().Equals(""))
The problem is that if it is null, it is still checking the condition on the right-hand-side.
Any ideas?
You can do:
if (table.ExtendedProperties["MS_Description"] == null || string.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value))
The reason your code errors is because you don't check if table.ExtendedProperties["MS_Description"].Value is null.
Thus Value is not a string, then you have to deal with all conditions:
var description = table.ExtendedProperties["MS_Description"];
if (description == null ||
description.Value == null ||
description.Value.ToString().Equals(""))
// no value
BTW your code is not quite correct
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value.ToString().Equals(""))
Instead of checking Value for null, you are checking if table.ExtendedProperties["MS_Description"] is not null. Thats true. You go further, but if table.ExtendedProperties["MS_Description"].Value is null (you didn't check that, remember?), you will get NullReferenceException on applying ToString().
I'm not sure if you are referring to the DataTable.ExtendedProperties property or something else, but if you are, the property returns a System.Data.PropertyCollection, which inherits from System.Collections.HashTable.
Most of the methods and properties, including the indexer ("Item") being discussed here, are directly inherited from HashTable, so in general, table.ExtendedProperties[key] can return any object, including null.
Note that you can also call DataTable.ExtendedProperties.ContainsKey(object key) to determine if the PropertyCollection contains a specific key or not.
Do you know what type of object you are retrieving when you call table.ExtendedProperties["MS_Description"].Value ?
If so, there might be other properties you can use to determine whether the property has been set, etc.
Depending on what type of object table.ExtendedProperties["MS_Description"] is, you might even be able to do something like this:
if ((table.ExtendedProperties["MS_Description"] ?? "").ToString().Length == 0) {
.....
}
That would take into account all of the possibilities:
the key doesn't exist
the key exists, but the value is null
the key exists and the value is empty
as long as the table.ExtendedProperties["MS_Decription"] object returns "" when its Value property is either null or empty.
So a little more information on the object that is returned could go a long way!
string.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value)
It looks like table.ExtendedProperties["MS_Description"] is never null, you should be null checking the Value property instead
string value = table.ExtendedProperties["MS_Description"].Value;
if (value == null || value.ToString().Equals(""))
// OR
if (String.IsNullOrEmpty(value))
If table.ExtendedProperties["MS_Description"] can return null, then you need
if (table.ExtendedProperties["MS_Description"] == null ||
String.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value.ToString() )
And since table.ExtendedProperties["MS_Description"].Value may return null, then you need
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value == null ||
String.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value.ToString() )
I have a class with a string property. I use the coalesce operator when reading from it as it might be null, but it still throws me an NullRefrenceExeption.
string name = user.Section.ParentSection.Name ?? string.Empty;
To be more specific, its the ".ParentSection" that's null so is it because it don't even have ".name" ? If that's the case should i test ".ParentSection" first with an if block?
I assume there are something about the Coalesce operator i dont understand, hope someone can shed some light on whats going wrong here.
To be more specific, its the ".ParentSection" that's null so is it
because it don't even have ".name" ?
Yes.
If that's the case should i test ".ParentSection" first with an if
block?
Yes.
You'll need to check if Section and ParentSection are null. You could use an if-statement for this or write an extension method like this:
public static class MaybeMonad
{
public static TOut With<TIn, TOut>(this TIn input, Func<TIn, TOut> evaluator)
where TIn : class
where TOut : class
{
if (input == null)
{
return null;
}
else
{
return evaluator(input);
}
}
}
You would use this method like so:
string name = user.With(u => u.Section)
.With(s => s.ParentSection)
.With(p => p.Name) ?? string.Empty;
I think it's a lot cleaner than an if-statement with a lot of &&.
Some further reading: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
You need to check if user, user.Section, or user.Section.ParentSection are null before you can use the null coalescing operator on a property of user.Section.ParentSection.
Nested property access is not safe if any of the objects accessed are null this will throw a NullReferenceException. You will have to explicitly test for the outer objects to be not null.
E.g.:
string name = string.Empty;
if(user!=null && user.Section!=null && user.Section.ParentSection !=null)
name = user.Section.ParentSection.Name ?? string.Empty;
In general I would try to avoid nested access to properties, you are violating the Law of Demeter. Some refactoring might make this unnecessary in the first place.
The ?? operator checks if the left side is null and if so returns the right one, if not the left one.
In your case the left-side is the "Name" property in the object user.Section.ParentSection and this is null.
In those cases either think on what might be null or do something like this:
string name = user == null
|| user.Section == null
|| user.ParentSection == null
|| user.Section.ParentSection.Name == null
? string.Empty
: user.Section.ParentSection.Name;
(yeah it's ugly I know)
Chances are user or user.Section or user.Section.ParentSection is a null value.
The ?? operator doesn't prevent checks like:
if (user != null && user.Section != null && user.Section.ParentSection != null){
Make sure that everything up to the string property is valid and exists, then you can use ??. You can't call (null).Name, no matter how many times you try.
Yes you need to check if Section or ParentSection are null before you check Name
It is probably best to do something like this:
if(user!=null && user.Section!=null && user.Section.ParentSection!=null)
{
string name = user.Section.ParentSection.Name ?? string.Empty;
}
The null coalescing operator takes a statement like:
a = b ?? c;
What this says is "evaluate b; if it has a non-null value then assign that to a. Otherwise assign the value of c to a".
However within your b you're using a user object which may be null that has a section object that may be null that has a parent section property that may be null that had a name property that may be null. If you wanted to check all of these (and typically you should) then you can do something like:
string name = string.Empty;
if (user != null &&
user.Section != null &&
user.Section.ParentSection != null)
{
name = user.Section.ParentSection.Name ?? string.Empty;
}
As soon as the IF check fails it will not check further and therefore you don't get a NullReferenceException when you assume an object is present and then try to access one of its properties.
I've ran into an issue where code classes outside of my control use strings that are null so when they become referenced for example, "string.Length", causes an error. Rather than write a check for the possible 100 fields on average, with nested classes, I thought maybe I could create something easier. I had an idea...
If you've done any research into copying objects PropertyCopy, along with a few others, is an extremely common find. I currently use the class mentioned above. I was wondering if it could be modified to simply go:
if stringPropertyValue is null then set stringPropertyValue equal to string.Empty.
My understanding is limited. I've been doing research to solve my issue but no real good ideas. Can my idea work? Is there a better way? How would it be done if it could?
Update:
Based on a response below I have created this class which I am currently going to use.
public static void DenullifyStringsToEmpty<T>(this T instance)
{
//handle properties
foreach (var filteredProperties in instance.GetType().GetProperties().Where(p =>
(p.PropertyType.IsClass || p.PropertyType.IsInterface || p.PropertyType == typeof(string))))
{
if (filteredProperties.PropertyType == typeof(string))
{
if (filteredProperties.GetValue(instance, null) == null)
{
filteredProperties.SetValue(instance, string.Empty, null);
}
}
else
{
filteredProperties.GetValue(instance, null).DenullifyStringsToEmpty();
}
}
//handle fields
foreach (var filteredFields in instance.GetType().GetFields().Where(f =>
(f.FieldType.IsClass || f.FieldType.IsInterface || f.FieldType == typeof(string))))
{
if (filteredFields.FieldType == typeof(string))
{
if (filteredFields.GetValue(instance) == null)
{
filteredFields.SetValue(instance, string.Empty);
}
}
else
{
filteredFields.GetValue(instance).DenullifyStringsToEmpty();
}
}
}
I know that reflection can be heavy and until we have an issue I think this solution will work great. This is an extension (thanks to the comments below).
Thanks for the input.
Couldn't you just create a simple extension method?
public static string NullToEmpty(this string possibleNullString)
{
return possibleNullString ?? string.Empty;
}
Use this, when accessing the string properties of that third party classes, e.g.:
var length = instanceOfThirdPartyClass.StringProperty.NullToEmpty().Length;
Update:
Now that I understand what you want ;-)
Have a look at this:
public static void DenullStringProperties<T>(this T instance)
{
foreach(var propertyInfo in instance.GetType().GetProperties().
Where(p => p.PropertyType == typeof(string))
{
var value = propertyInfo.GetValue(instance, null);
if(value == null)
value = string.Empty;
propertyInfo.SetValue(instance, value, null);
}
}
You could call it like this:
instanceOfThirdPartyClass.DenullStringProperties();
But I still think you should go with the first approach, because I really don't see a reason to do such heavy lifting during runtime (reflection isn't cheap), just because you are lazy about typing during development :) Additionally, you can't be sure that the properties will stay non null after you have called DenullStringProperties (multi-threading, calls to methods of the object, ...). The first approach checks for null and handles it just as it is needed.
This question already has answers here:
Best and fastest way to check if an object is null [duplicate]
(6 answers)
Closed 9 years ago.
What is the most efficient way to check for null references on objects? I have seen various code samples that have different ways of checking so of the following which is the most efficient or the one that it is considered best practice to use?
Object.ReferenceEquals(item, null)
item == null
item != null
Object.Equals(item, null)
thanks
Object.ReferenceEquals(item, null) compare references and equals to item == null.
Object.Equals(item, null) compare references for reference types and bitwise for value types, but in reflector it's equal to (item == null) || ((item != null && null != null) && item.Equals(null)).
item != null code not always equals to !(item == null), but of course result should be equal.
item == null code not equals to null == item, it's similar to typeof(item).Equals(object) and object.Equals(typeof(item)) method calls.
It differ because you can override !=, ==, Equals.
Use methods with known implementation, null == item is better to code, but harder to read.
Object.ReferenceEquals(null, item) may be faster or not.
P.S. use string.IsNullOrEmpty(item) too
For comparing to null, I'd use == or != always, because for null it should always give the same result as ReferenceEquals and Equals anyway (so no need for the extra code).
Edit: It's true that == could be overridden to give a wrong result for null (i.e., true) but that means the override is buggy. To make the code readable I would stick with == and !=.
Updated answer
As of C# 7.0 is you can use:
item is null
should be the simplest and most foolproof way. It's same as ReferenceEquals check.
Old answer:
1)
Object.ReferenceEquals(item, null)
This is a good way. Not as concise as I would love, but still great and tells u the intent exactly.
2)
item == null
item != null
There is nothing wrong with this (which is the most elegant) if you are sure == and subsequently != is overloaded correctly. Its easy to write (overload) bad equality operators (and often done). But the real trouble is when you are trying to overload == operator in a class (lets say of value semantic). You cant use == for null checks inside == overloading function of the class since that will cause an infinite recursion. To have one consistent style, I rely on something else.
3)
Object.Equals(item, null)
Again it internally does a ReferenceEquals so there is not much point, but if it semantically makes more sense to you, then go with this.
4)
My approach is to do
(object)item == null
upon which I'm relying on object's own equality operator which can't go wrong. Not so readable so I just wrap in a custom extension method and an overload:
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null;
}
public static bool IsNull<T>(this T? obj) where T : struct
{
return !obj.HasValue;
}
It makes more sense since I will need to check against DBNulls too often. So now I have one consistent style all over!
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null || obj == DBNull.Value;
}
(Do not take off the (object) casting as that's what will prevent infinite recursion when overloading == as stated before)
Additionally the constraint prevents IsNull on value types. Now its as sweet as calling
object obj = new object();
Guid? guid = null;
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error
I also have found (object)item == null is very very very slightly faster than Object.ReferenceEquals(item, null) or object.Equals(,) for that matter, but only if it matters (I'm currently working on something where I've to micro-optimize everything!).
To see a complete guide on implementing equality checks, see What is "Best Practice" For Comparing Two Instances of a Reference Type?
As an extra, don't forget code contracts in .NET 4.0!
System.Diagnostics.Contracts.Contract.Requires(item != null);
Which is not only nice and clear, but allows compile time checking. See Code Contracts in msdn.
ReferenceEquals is equivalent to (object)o1==(object)o2. It may be faster than o1==o2 if the equality operator is overloaded. Object.Equals is probably a bit slower.
The difference between == and != isn't performance, but how your program should look like. They can be a bit slower if the == and != operator are overloaded.
But I don't think the performance difference between them matters at all. I'd choose the one that's easiest to read. And that's usually == or !=.
If I throw an exception I usually use == as in:
if(o == null)
throw new ...;
If null results in a no-op then usually != is appropriate
if(x != null)
{
...
}
I always use
item != null
but this is harder to read than
item == null
Object.ReferenceEquals is used to check whether two objects are the same instance.
First 2 are the same effectively.
The last however does not only do a reference check, and should not be used for null checking.