Macro-like structures in C # == OR == How to split a function containing 'return'

I never thought I needed anything in this (since macros are bad, right?), But it turns out I do it.

I repeat the following pattern over and over in my code, dozens, if not hundreds of times:

object Function() {
    this.Blah = this.Blah.Resolve(...);
    if(this.Blah == null)
        return null;
    if(this.Blah.SomeFlag)
        return this.OtherFunction();

    // otherwise, continue processing...
}

I would like to write something like this:

object Function() {
    this.Blah = this.Blah.Resolve(...);
    VerifyResolve(this.Blah);

    // continue processing...
}

Except for the fact that the template contains conditional return, it means that I cannot decompose the function. I had to subtly change the template once, and since I could not perform a simple search, it was painful to find all instances.

How can I avoid unnecessary repetition and make any future changes to this template easier?

+3
source share
7

- :

object Function()
{ 
    this.Blah = this.Blah.Resolve(...);
    object rc;
    if (!VerifyResolve(out rc)
       return rc;

    // continue processing... 
} 

bool VerifyResolve(out object rc)
{
    if(this.Blah == null)      
    {
        rc = null;
        return true;
    }
    if(this.Blah.SomeFlag)      
    {
        rc = this.OtherFunction();
        return true;
    }
    rc = null;
    return false;
}
+1

, null, Null Object Pattern. , , . null. , . - :

MyClass Function() 
{  
  this.Blah = this.Blah.Resolve(...); 
  VerifyResolve(this.Blah);

  // continue processing...  
}  

MyClass VerifyResolve(MyClass rc) 
{
  // ...
  return rc.Blah.SomeFlag ? rc.OtherFunction() : rc;
} 

NullMyClass : MyClass {
  public override bool SomeFlag { get { return false; } }
}
+3

, :

if (!TryResolve(this.Blah)) return this.Blah;

TryResolve this.Blah null, this.OtherFunction bool

+1

, :

this.Blah = this.Blah.Resolve(...);

, , .

, , - , . , - , , , .

, , , : , , , !

, , , , :

class ExampleExpr{
    StatefulData data ... // some variables that contain the state data
    BladhyBlah Blah { get; set; }

    object Function(params) {
        this.Blah = this.Blah.Resolve(params);
        ....
    }
}

, , , , . . , Function(), , Blah, , .

class ExampleExpr{
    StatefulData data ... // some variables that contain the state data

    object Function(params) {
        BlahdyBlah blah = BlahdyBlah.Resolve(params, statefulData);
    }
}

factory -style, , , , (.. BladhyBlah ).

, , (params) Setup(), statefulData .

( BlahdyBlah factory), BlahdyBlah factory ( , , ). , maintanence .

, , , (params, statefulData) (params) (params), blah == null blah.SomeFlag == SomeFlag.Whatever. , , .

, - , , , , / .

+1

Blah VerifyResolve extantion. Blah, IVerifyResolveble Blah .

0
object Function() { 
    this.Blah = this.Blah.Resolve(...);
    object result;
    if (VerifyResolve(this.Blah, out result))
        return result;

    // continue processing... 
} 
0
source

It's dirty, annoying and verbose, but that's what I had to go with. There is probably no better way.

Another way is to create a structure whose zero significance is significant.

struct Rc
{
  internal object object;
  internal Rc(object object) { this.object = object; }
}

object Function() 
{  
    this.Blah = this.Blah.Resolve(...); 
    Rc? rc = VerifyResolve();
    if (rc.HasValue)
       return rc.Value.object; 

    // continue processing...  
}  

Rc? VerifyResolve() 
{ 
    if(this.Blah == null)       
    { 
        return new Rc(null); 
    } 
    if(this.Blah.SomeFlag)       
    { 
        return new Rc(this.OtherFunction()); 
    } 
    return null; 
} 
0
source

Source: https://habr.com/ru/post/1751353/


All Articles