Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforcing required function call

I have a "Status" class in C#, used like this:

Status MyFunction()
{
   if(...) // something bad
     return new Status(false, "Something went wrong")
   else
     return new Status(true, "OK");
}

You get the idea. All callers of MyFunction should check the returned Status:

Status myStatus = MyFunction();
if ( ! myStatus.IsOK() )
   // handle it, show a message,...

Lazy callers however can ignore the Status.

MyFunction(); // call function and ignore returned Status

or

{
  Status myStatus = MyFunction(); 
} // lose all references to myStatus, without calling IsOK() on it

Is it possible to make this impossible? e.g. an throw exception

In general: is it possible to write a C# class on which you have to call a certain function?

In the C++ version of the Status class, I can write a test on some private bool bIsChecked in the destructor and ring some bells when someone doesn't check this instance.

What is the equivalent option in C#? I read somewhere that "You don't want a destructor in your C# class"

Is the Dispose method of the IDisposable interface an option?

In this case there are no unmanaged resources to free. Additionally, it is not determined when the GC will dispose the object. When it eventually gets disposed, is it still possible to know where and when you ignored that specific Status instance? The "using" keyword does help, but again, it is not required for lazy callers.

like image 558
jan Avatar asked Aug 21 '08 09:08

jan


2 Answers

I know this doesn't answer your question directly, but if "something went wrong" within your function (unexpected circumstances) I think you should be throwing an exception rather than using status return codes.

Then leave it up to the caller to catch and handle this exception if it can, or allow it to propogate if the caller is unable to handle the situation.

The exception thrown could be of a custom type if this is appropriate.

For expected alternative results, I agree with @Jon Limjap's suggestion. I'm fond of a bool return type and prefixing the method name with "Try", a la:

bool TryMyFunction(out Status status)
{
}
like image 172
Ian Nelson Avatar answered Oct 12 '22 12:10

Ian Nelson


If you really want to require the user to retrieve the result of MyFunction, you might want to void it instead and use an out or ref variable, e.g.,

void MyFunction(out Status status)
{
}

It might look ugly but at least it ensures that a variable is passed into the function that will pick up the result you need it to pick up.

@Ian,

The problem with exceptions is that if it's something that happens a little too often, you might be spending too much system resources for the exception. An exception really should be used for exceptional errors, not totally expected messages.

like image 44
Jon Limjap Avatar answered Oct 12 '22 13:10

Jon Limjap