Natio2
Natio2

Reputation: 245

C# return a jump statement from a function

As all coders I hate repeated blocks of code, but as a C++ dev I really want the null checks as it has been burnt into me meaning a have a lot of blocks that look like

if(object == null)
{
    //For loops
    continue;

    //To check function inputs/creation
    return; //maybe with a value
}

I know I could put a try/catch around everything, but I really don't like that style of coding

Is there a way to replace the null check block with a generic function. Something like

jumpstatement CheckNull<T>(T thingToCheck)
{
    if(thingToCheck == null)
    {
        return continue;
    }
    return null;
}

Then in the actual code instead of the old repeated blocks I'd have just the function (padded out as requested)

for(int i = 0; i < myCollection.Count; i++){
    //Function forces a "continue;" call if null
    CheckNull(myCollection[i]);

    //Do some stuff with myCollection[i]
}

The closest thing I could see was talking about code snippits or inline functions but I really don't think that's what I want.

Upvotes: 1

Views: 404

Answers (2)

Joel Coehoorn
Joel Coehoorn

Reputation: 416131

C# 8 has a new feature called nullable reference types that's even better. You add a few annotations here and there, and then the compiler can handle a lot of this for you. You get to just write the code you want to write, without worrying a reference might accidentally be null. It takes some getting used to, but it's pretty cool once you've mastered the concept.

Aside from that, you can't return an arbitrary jump or goto... but you can return a delegate. This is similar to C/C++ function pointer. You can theoretically use this to turn this proposed call:

CheckNull(someObject);

into this:

CheckNull(someObject)();

where the return value of CheckNull() is a method you want to call. But more practically, it would probably look more like this:

CheckNull(someObject, o => {
   //Do something with someObject here, where you can be **sure** someObject is not null
});

You could even embed a lock into your method to keep things more thread-safe.

public void CheckNull<T>(T target, Action<T> action)
{
    if (target is object)
    {   //naive implementation -- potential thread race between these two lines
        // ... but it does narrow the race to JUST those two lines, regardless of how much work is hidden in the action.
        lock(target)
        {
           action(target);
        }
    }
}

The other thing you can do is use Where() operation. So if you have an array like this

object[] items = new object[100];  
FillArray(items);

You can write code like this loop over only the items that are not null:

foreach(var item in items.Where(i => i is object))
{
   //item will not be null, as long as you're in a single thread. Otherwise, lock on something first.
}

Upvotes: -1

Alex
Alex

Reputation: 632

I don't think what you want to do here is possible. Basically, you want to be able to call a function which affects control flow in the function calling it (e.g. you want to be able to return from the calling function from your function). This is not possible with a normal function.

This sort of thing is possible in C/C++ using function-like macros, and in several other languages which support "real" macros. Unfortunately, C# does not have macros, so this sort of thing can't be done in the way you want.

Upvotes: 2

Related Questions