Home > Blockchain >  function that returns two different types
function that returns two different types

Time:12-24

i should have a function that must returns or a string of an error (through try/catch) or a different type. Exemple of function:

public T get()
{
 T struttura;
 try{...}
 catch (Exception xcp){return xcp.Message;}
 ...
 return struttura;
}

CodePudding user response:

There are ways to do this, but really consider if that's what you actually want. It is almost always better just to let the Exception bubble upwards into the calling code.

The first way is to use an out parameter.

public string get(out T result)
{
 T struttura;
 try{...}
 catch (Exception xcp)
 {
  result = default(T);
  return xcp.Message;
 }
 ...
 result = struttura;
 return String.Empty;
}

The second way is to use a ValueTuple:

public (T, string) get()
{
 T struttura;
 try{...}
 catch (Exception xcp){return (default(T), dexcp.Message);}
 ...
 return (struttura, string.Empty);
}

CodePudding user response:

The .net design guidelines https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exception-throwing recommend never returning the exception as a return type. It’s always better design to throw the error and catch in the caller.

The guidelines also recommend that if you don’t want to throw the error that you can follow the TryParse pattern https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions-and-performance#try-parse-pattern. Typically you provide both methods, Get and TryGet. The presence of the Try method should indicate to callers that Get will throw exceptions but TryGet won’t. The TryGet also returns a Boolean if the operation was successful, allowing you to handle negative cases without using a try/catch block on the caller.

CodePudding user response:

I suggest TryGet signature:

public bool TryGet(out T struttura) {
  try {
    ...
    struttura = ...
    ...

    return true;
  }
  catch (Exception xcp){
    struttura = default(T);

    return false; 
  }
}

usage:

if (TryGet(out var myStruct)) {
  // succeeded, myStruct is returned struttura
}
else {
  // failed
}

Or either do not catch exception at all or re-throw the exception:

public T Get() {
  try {
    ...
    return struttura;
  }
  catch (Exception xcp) {
    throw new MyException("My message", xcp);
  }
}

usage:

try {
  myStruct = Get();
}
catch (MyException e) {
  // Failed, e.Message for message
  Console.WriteLine(e.Message);
}

Finally, you can mechanically combine value and message and return named tuple:

public (T value, string message) Get() {
  try {
    ...
    return (struttura, null);
  }
  catch (Exception xcp) {
    return (default(T), xcp.message);
  }
}

usage:

var result = Get();

if (result.message == null) {
  // succceded with result.value
}
else {
  // failed with result.message
}
  •  Tags:  
  • c#
  • Related