Is There a Safe Navigation Operator for C++

Is there a safe navigation operator for C++?

The best you can do is collapse all the member accesses into one function. This assumes without checking that everything is a pointer:

template <class C, class PM, class... PMs>
auto access(C* c, PM pm, PMs... pms) {
if constexpr(sizeof...(pms) == 0) {
return c ? std::invoke(pm, c) : nullptr;
} else {
return c ? access(std::invoke(pm, c), pms...) : nullptr;
}
}

Which lets you write:

if (auto r = access(p, &P::q, &Q::r); r) {
r->doSomething();
}

That's ok. Alternatively, you could go a little wild with operator overloading and produce something like:

template <class T>
struct wrap {
wrap(T* t) : t(t) { }
T* t;

template <class PM>
auto operator->*(PM pm) {
return ::wrap{t ? std::invoke(pm, t) : nullptr};
}

explicit operator bool() const { return t; }
T* operator->() { return t; }
};

which lets you write:

if (auto r = wrap{p}->*&P::q->*&Q::r; r) {
r->doSomething();
}

That's also ok. There's unfortunately no ->? or .? like operator, so we kind of have to work around the edges.

Safe Navigation Operator in C#?

For such cases I tend to use an extension method called IfNotNull:

public static OUT IfNotNull<IN, OUT>(this IN v, Func<IN, OUT> f) 
where IN : class where OUT : class
{
return v == null ? null : f(v);
}

More sophisticated is to introduce the notion of a Maybe . An example was brought by derick bailey here.

Update:

As of C# 6 there is now a null-propagating operator which syntax-wise looks exactly like the Groovy one.

Safe Navigation Operator with Any()

Here is what C# reference says about ?. operator:

x?.y – null conditional member access. Returns null if the left hand
operand is null.

Since at compile time the compiler doesn't knows whether the expression will evaluate to a non-null value, the compiler infers the type as Nullable<bool>

Since you are chaining the ?. operator this line from msdn documentation is relevant too:

The null-condition operators are
short-circuiting. If one operation in a chain of conditional member
access and index operation returns null, then the rest of the chain’s
execution stops. Other operations with lower precedence in the
expression continue. For example, E in the following always executes,
and the ?? and == operations execute.

Can a C# Safe Navigation Operator (?.) be used to check if Object is null, as well as property?

The first is equivalent to

if (_instanceData != null && _instanceData.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}

The second is equivalent to

if (LockAcquired && _instanceData != null && _instanceData.ObjInfo != null) {// code}

So it will check if _instanceData is null, then check if _instanceData.DataSourceType is null, then the last condition. As you said, this is just syntactical sugar so you don't have to write two != null conditions. The IL code that results is exactly the same, so its a matter of preference whether or not to use the operator.

It does save a TON of space when accessing deeply nested properties, which is where its most useful

if(Parent != null)
{
if(Parent.Child != null)
{
if(Parent.Child.GrandChild != null)
{
Parent.Child.GrandChild.GreatGrandChild.name = "Parent IV";
}
}
}

becomes

Parent?.Child?.GrandChild?.GreatGrandChild.name = "Parent IV";

Saves a lot of space! Even if you collapsed all the ifs into one statement it still saves loads of keystrokes and screen noise.

C# Safe navigation operator - what is actually going on?

Let's walk through this logically.

var f = ???;
var i = f?.Measure;
var t = i.HasValue;

We don't know if f is null or not.

  1. If f is null, then the result (i) is null
  2. If f is not null, then the result (i) is an int

Therefore, i is defined as int?, and t is a bool

Now, let's walk through this:

var f = ???;
var i = f?.Measure.HasValue;
  1. If f is null, then the result (i) is null
  2. If f is not null, then the result (i) is Measure.HasValue, which is a bool.

Therefore, i is a bool?.

If f is null, we short-circuit and return null. If it's not, we return the bool result of .HasValue.

Essentially, when using ?. - the return type must be a reference value, or a Nullable<T>, as the expression can short circuit to return null.

What's the best implementation of safe navigation operator

That operator does not exist in C#. You could do it with an inline-if

int respId = SessionData.CurrentSeminar != null ? 
SessionData.CurrentSeminar.SeminCbaRespId : default(int);

or as an extension method.

var respId = SessionData.CurrentSeminar.GetSeminCbaRespId();

public static int GetSeminCbaRespId(this typeofCurrentSeminar CurrentSeminar)
{
return CurrentSeminar != null ? CurrentSeminar.SeminCbaRespId : default(int);
}

Safe Navigation of indexed objects

Based on the Language Feature Status Page it looks like you want:

var singleElement2 = myClass2?.ArrayOfStrings?[0];

The example on the page is:

customer?.Orders?[5]?.$price

... admittedly the $price part has been withdrawn now, I believe, but I would expect the indexed null propagation to work.

Safe navigation operator (?.) or (!.) and null property paths

Since TypeScript 3.7 was released you can use optional chaining now.

Property example:

let x = foo?.bar.baz();

This is equvalent to:

let x = (foo === null || foo === undefined)
? undefined
: foo.bar.baz();

Moreover you can call:

Optional Call

function(otherFn: (par: string) => void) {
otherFn?.("some value");
}

otherFn will be called only if otherFn won't be equal to null or undefined

Usage optional chaining in IF statement

This:

if (someObj && someObj.someProperty) {
// ...
}

can be replaced now with this

if (someObj?.someProperty) {
// ...
}

Ref: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html

What does the safe navigation operator look like for closures in Groovy?

You should be able to use the longer call() form, ie:

c?.call( 'hello world?' )


Related Topics



Leave a reply



Submit