The null-conditional operator is very useful when the method belongs to the object in question, but what if the object in question is an argument? For example, can this be shortened?
var someList = new List<SomeType>();
if (anotherList.Find(somePredicate) != null)
{
someList.Add(anotherList.Find(somePredicate))
}
One solution I thought of was to use an extension method like below:
public static void AddTo<T>(this T item, List<T> list)
{
list.Add(item);
}
With that the first code block can be reduced to:
var someList = new List<SomeType>();
anotherList.Find(somePredicate)?.AddTo(someList);
But this solution is specific to this example (i.e. adding an object to a list if it's not null). Is there a general way to indicate that if a parameter is null, the method should not be run?
Never do this
var someList = new List<SomeType>();
if (anotherList.Find(somePredicate) != null)
{
someList.Add(anotherList.Find(somePredicate))
}
this will search the list twice which is unnecessary. use a temporary variable instead.
var someList = new List<SomeType>();
var find = anotherList.Find(somePredicate);
if (find != null) someList.Add(find);
Is there a general way to indicate that if a parameter is null, the method should not be run?
Currently there is no such feature. how ever there are other alternatives that work better like in other answers provided.
You could also use just:
var someList = new List<SomeType>();
someList.AddRange(anotherList.Where(somePredicate));
In your case you probably need to make sure that your predicate only finds at max one element.
TLDR: Not yet.
The team plans to implement a functionality into the language, that would do this exact thing. It would look something like this:
someList.Add(anotherList.Find(somePredicate) ?? return);
In which the ?? return checks whether the first argument is null, and if it is, than it returns. (Or you could write break if that is what you want)
I am not sure if this is a thing they are working on at the moment, and if it will be included in the next version of C#, but would go a long way if it is going to be.
Related
I'm trying to do smth like
Im trying to assign property on an object if this object is not null.
but standard form of non-null invocation does not work for assignment like this
socket?.Blocking = false
what I'm trying to do is shorten this if possible:
if(socket != null) socket.Blocking = false
This would be a great feature
b?.c = "bob"
Though, it's flawed when it comes to compound assignments. Consider this
a.b?.c = "bob"
What should it do on null?
Personally, I think it should just ignore the parents. But alas, the powers that be have probably made the right decision to disallow this because of inconsistency with the other use cases of null conditional.
Note : you could roll your own an extension method, though it's not very satisfying, and would probably fail my code reviews just on abstractness and readability.
a?b.NullConditional(x => x.c = "bob");
You are left with
if(a?.b != null) a.b.c = "bob"
or in your case
if(socket != null) socket.Blocking = false
or to write a dedicated extension method for this use case.
I think the only way would be to use an extension method, so you could write:
socket?.SetBlocking(false);
You can create the extension method like this:
public static class SocketExtensions
{
public static void SetBlocking(this Socket socket, bool blocking)
{
if (socket != null) socket.Blocking = blocking;
}
}
Let's suppose I have a very simple IEnumerable that looks like this:
IEnumerable<string> foo = new[] { "Apple", null, "Orange" };
I would like to check if it contains a null item. Based on what I found with Google, I can do this as follows:
bool containsNull = foo.Any(item => item == null);
What about the Enumerable.Contains method? The following seems pretty obvious to me, but I've never seen it this way:
bool containsNull = foo.Contains(null);
Is there any problem with the previous expression that results in the Enumerable.Any method used instead?
It's true, in most of the cases Contains(null) will do the work. But there is a vulnerability for ArgumentNullException. An example can be:
string foo = "foo";
bool containsNull = foo.Contains(null); //throws exception
In your case, you've already set the generic type as string so it is safe to use Contains.
The "Contains" operator checks whether a specified element exists in the collection or not and returns a boolean.
"Any" checks whether any element satisfy given condition or not? In the following example, Any operation is used to check whether any student is teen ager or not.
In this case is better use "ANY"
yo can to visit https://www.tutorialsteacher.com/linq/linq-quantifier-operators
I have a situation where I need to assign some objects' properties inside an object initializer. Some of these objects can be null and I need to access their properties, the problem is that they are too many, and using a if/else thing is not good.
Example
visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
VisiteId = joined.Visite.VisiteId.ToString(),
NomPointDeVente = joined.VisitePdvProduit.PointDeVente.NomPointDeVente,
});
The joined.VisitePdvProduit can be null, and the problem is that there are like dozens of such assignments (I just took one to shorten the code)
The C# 6 Null-Conditional operator is the perfect solution for this situation, the problem is that I'm on C# 5 in this project, is there a way to imitate that ?
Well, you can use an extension method that receives an accessor delegate and only executes it if the item isn't null:
public static TResult ConditionalAccess<TItem, TResult>(this TItem item, Func<TItem, TResult> accessor) where TResult : Class
{
if (item == null)
{
return null;
}
else
{
return accessor(item);
}
}
You can use it for example like this:
NomPointDeVente = joined.VisitePdvProduit.ConditionalAccess(_ => _.PointDeVente.NomPointDeVente);
You can easily create versions of this method for operations that don't return a value (i.e. bar.ConditionalAccess(_ => _.Foo())) or return value types.
Like this. Ugly, but what had to be done.
visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
VisiteId = joined.Visite.VisiteId.ToString(),
NomPointDeVente = (joined.VisitePdvProduit == null) ? null : joined.VisitePdvProduit.PointDeVente.NomPointDeVente,
});
If you are talking about the semi-very surprised operator ?., then no. There's no way to mimic the syntax.
What you can do, though, is to create an extension method (or a helper method, static one, preferably) or an instance method working with the properties.
Or, as someone suggested, just use the conditional statement (inline or explicit). But that's not what you're looking for, of course.
One more method (and it's not at all recommendable) is to surround the assignment with a try-catch. But that's really baaad solution and I only mention it for completeness' sake.
So insteed of writing:
if (obj.Collection == null)
obj.Collection = new Collection();
obj.Collection.Add(something);
I thought of writing:
obj.Collection = obj.Collection ?? new Collection;
obj.Collection.Add(something);
It kind of feels wrong, especially this part "obj.Collection = obj.Collection..."
What do you guys think ?
Regards,
If I had to choose between these two blocks of code, I would use the former. It's more readable and it's a common pattern. ?? is useful in scenarios where you need to default a value (e.g., DateTime date = nullableDateTimeInstance ?? defaultDate;).
But frankly, I'd try to not end up in situation where I want to add to collection and it's possible that the collection is null. Instead, I'd make sure that the collection is initialized in the constructor or whatever the case may be.
Do you mean:
if (obj.Collection == null)
{
obj.Collection = new Collection();
}
obj.Collection.Add(something);
If so, you can rewrite it as
(obj.Collection = (obj.Collection ?? new Collection())).Add(something);
The code will emit an unnecessary assignment (of obj.Collection to itself) if obj.Collection is not null, but other than that it is equivalent to the original.
Looks fine to me provided you don't use it in time critical sections. Anyway it's possible the compiler can optimise the assignment away, but I don't know if it would or not.
Perhaps it just feels wrong because the original code is such a common and simple pattern that it feels wrong to change it.
I'd say it also depends on what the setter of the Collection property does. Consider this:
public Collection Collection
{
get { return _collection; }
set
{
_collection = value;
Thread.Sleep( 1000 ); // or some expensive real work
}
}
In this case, the assignment obj.Collection = obj.Collection ?? new Collection() would be really costly.
However, if you need to create a collection "on demand", it's common to use a similar pattern in the property getter, like this:
public Collection Collection
{
get { return _collection ?? ( _collection = new Collection() ); }
}
Is this possible without reflection otherwise with reflection ? This is something very often used in PHP like in Wordpress.
Something in pseudo code:
if (exists(object.method)) {object.method}
or
try {object.method} finally {...}
Well, you could declare it in an interface, and then use:
IFoo foo = bar as IFoo;
if (foo != null)
{
foo.MethodInInterface();
}
That assumes you can make the object's actual type implement the interface though.
Otherwise you'd need to use reflection AFAIK.
(EDIT: The dynamic typing mentioned elsewhere would work on .NET 4 too, of course... but catching an exception for this is pretty nasty IMO.)
You could use dynamics and catch the Runtime exception:
dynamic d = 5;
try
{
Console.WriteLine(d.FakeMethod(4));
}
catch(RuntimeBinderException)
{
Console.WriteLine("Method doesn't exist");
}
Although it sounds more like a design problem.
Disclaimer
This code is not for use, just an example that it can be done.
Use .GetType().GetMethod() to check if it exists, and then .Invoke() it.
var fooBar = new FooBarClass();
var method = fooBar.GetType().GetMethod("ExistingOrNonExistingMethod");
if (method != null)
{
method.Invoke(fooBar, new object[0]);
}
With the dynamic type in C# 4.0, you could do something like this:
dynamic obj = GetDynamicObject();
if (obj != null && obj.GetType().GetMethod("DoSomething") != null)
{
obj.DoSomething();
}
But the only way to tell if a type has a method in the first place is to use reflection; so the above approach doesn't really buy you anything (you might as well take the MethodInfo you get from calling GetMethod and just Invoke it).
Edit: If you're open to trying to call the method even when it's not there, then Yuriy's answer is probably what you're looking for. My original answer was a literal response to the way you worded your question: "How to call a C# method only if it exists."
I came across this looking for the same answer but did not like any of the solutions.
here is mine:
//Invoke the refresh method if the datasource contains it
if (this.DataSource.GetType().GetMethod("Refresh") != null)
this.DataSource.GetType().GetMethod("Refresh").Invoke(this.DataSource, new object[] { });
You should revise existance first. MethodInfo[] myArrayMethodInfo = myType.GetMethods();