I want to add an interface to some built-in types. I have an interface, IConcludable
, which I am using as a constraint for Conclusion<T>
. I have no clue how to approach this, or if it is even possible.
Basic Layout
public interface IConcludable { }
public struct Conclusion<T> where T : IConcludable
{
public bool IsSuccessful;
public T Result;
// Constructors, members, etc.
}
public class ErrorReport : IConcludable { ... }
public class MathArg : IConcludable { ... }
public class ParseResult : IConcludable { ... }
Implementation
public Conclusion<ParseResult> ParseInput (string input)
{
// Parse input...
// Initialize ParseResult object...
return new Conclusion<ParseResult>(result);
}
Problem
When I get the final value, it is a built-in type like int
, double
, string
, bool
, etc. I would like to use Conclusion<T>
as a return because I have a class that handles error reports when the input string is invalid:
if (conclusion.ReturnObject is ErrorReport)
{
ErrorManager errorManager = new ErrorManager();
errorManager.Resolve(conclusion);
}
Research
I looked into constraints.
It appears that constraints only add together, so including the interfaces of each built-in type that I need would require defining a mountain of methods that do not have anything to do with my Conclusion
struct.
Extension methods
These actually change the behavior of built-in types. It is not what I am looking for because my interface, IConcludable
, does not have any methods.
Replacing built-in types
Not possible. I don't need to change the behavior of these types though. I just want to add an empty interface to it.
There does not seem to be anything regarding adding an interface to a built-in type. I'm not sure if "Inheritance" is what it would be referred to. Is this possible?
Edit
Better explanation of Conclusion struct
I am using the conclusion struct as a return object in most of my methods. This is because I am using delegates. See the actual code of the objects below:
public delegate Conclusion<T> Validator<T>(T subclass) where T : IVerifiable<T>;
public delegate Conclusion<BaseFunction> Executor(BaseFunction subclass);
public struct Conclusion<T> where T : IConcludable
{
public bool IsSuccessful;
public T ReturnObject;
public Conclusion(T returnObject)
{
this.ReturnObject = returnObject;
this.IsSuccessful = returnObject is Error ? false : true;
}
}
public class BaseFunction : IVerifiable<BaseFunction>, IConcludable
{
public List<BaseArgument> Args;
public Executor Executing;
public Validator<BaseFunction> Validating;
public string UserInput;
public Conclusion<BaseFunction> Validate(BaseFunction subclass)
{
if (this.Validating != null)
{
return Validating(subclass);
}
else
{
StringBuilder message = new StringBuilder();
message.Append("A Validating delegate has not been assigned.");
throw new InvalidOperationException(message.ToString());
}
}
public Conclusion<BaseFunction> Execute(BaseFunction subclass)
{
if (this.Executing != null)
{
return this.Executing(subclass);
}
else
{
StringBuilder message = new StringBuilder();
message.Append("An Executing delegate has not been assigned.");
throw new InvalidOperationException(message.ToString());
}
}
}
public class Function<T> : BaseFunction
{
public T Result;
public Function()
{
base.Args = new List<BaseArgument>();
}
}
public class BaseArgument : IVerifiable<BaseArgument>, IConcludable
{
public string Role;
public string UserInput;
public int Position;
public Validator<BaseArgument> Validating;
public Conclusion<BaseArgument> Validate(BaseArgument subclass)
{
if (this.Validating != null)
{
return Validating(subclass);
}
else
throw new InvalidOperationException();
}
}
public class Argument<T> : BaseArgument
{
public T Value;
public Argument(int position)
{
base.Position = position;
}
}
public static class ExecutionHandler
{
public static Conclusion<BaseFunction> Sum(BaseFunction subclass)
{
subclass = (Function<double>)subclass;
// Execution code.
return new Conclusion<BaseFunction>(subclass);
}
public static Conclusion<BaseFunction> Concatenate(BaseFunction subclass)
{
subclass = (Function<double>)subclass;
// Execution code.
return new Conclusion<BaseFunction>(subclass);
}
}
If I need to post more, I will. but it's really a lot to look at. The return type of the methods assigned by all of the delegates I use have a return type of Conclusion<T>
so that I can have a return object as well as an error if one occurs. The functions in the code above return Conclusion<BaseFunction>
, but that return is converted into an object Addend<T>
if it is a number. If it is a part of another type of function that returns a string
or bool
or other type, it is converted into a different type of class. By the end of a numeric calculation, the return will be something like Conclusion<int>
or Conclusion<double>
. So adding int
and double
to the IConcludable
interface is what I am trying to do.
Better explanation of the application
I am writing a C# console application. It takes input from the user, and writes an answer. The input is similar to Excel formulas: Sum(5, 15, Average(2, 3), 5)
or Concatenate("5 + 5 = ", Text(Sum(5, 5)))
. The input string is validated, parsed, and returns a result.