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.
I am fairly certain you can't get the effect you want as a return value from a method. C# just can't do some of the things C++ can. However, a somewhat ugly way to get a similar effect is the following:
using System;
public class Example
{
public class Toy
{
private bool inCupboard = false;
public void Play() { Console.WriteLine("Playing."); }
public void PutAway() { inCupboard = true; }
public bool IsInCupboard { get { return inCupboard; } }
}
public delegate void ToyUseCallback(Toy toy);
public class Parent
{
public static void RequestToy(ToyUseCallback callback)
{
Toy toy = new Toy();
callback(toy);
if (!toy.IsInCupboard)
{
throw new Exception("You didn't put your toy in the cupboard!");
}
}
}
public class Child
{
public static void Play()
{
Parent.RequestToy(delegate(Toy toy)
{
toy.Play();
// Oops! Forgot to put the toy away!
});
}
}
public static void Main()
{
Child.Play();
Console.ReadLine();
}
}
In the very simple example, you get an instance of Toy by calling Parent.RequestToy, and passing it a delegate. Instead of returning the toy, the method immediately calls the delegate with the toy, which must call PutAway before it returns, or the RequestToy method will throw an exception. I make no claims as to the wisdom of using this technique -- indeed in all "something went wrong" examples an exception is almost certainly a better bet -- but I think it comes about as close as you can get to your original request.