基本布局
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 { ... }
履行
public Conclusion<ParseResult> ParseInput (string input) { // Parse input... // Initialize ParseResult object... return new Conclusion<ParseResult>(result); }
问题
当我得到最终的值时,它是一个内置的类型,如int,double,string,bool等等.我想使用结论< T>作为一个返回,因为我有一个类,当输入字符串无效时处理错误报告:
if (conclusion.ReturnObject is ErrorReport) { ErrorManager errorManager = new ErrorManager(); errorManager.Resolve(conclusion); }
研究
我研究了约束.
> Is there a C# generic constraint for “real number” types?
似乎约束只是加在一起,所以包括我需要的每个内置类型的接口将需要定义一些与我的结论结构无关的方法.
扩展方法
> How to extend C# built-in types,like String?
这些实际上改变了内置类型的行为.这不是我正在寻找,因为我的界面,没有任何方法.
更换内置类型
> Overwrite built in .NET class
不可能.我不需要改变这些类型的行为.我只想添加一个空的界面.
将界面添加到内置类型似乎没有什么关系.我不知道“继承”是否会被引用.这可能吗?
编辑
更好地解释结论结构
在大多数我的方法中,我使用结论struct作为返回对象.这是因为我正在使用代理.请看下面对象的实际代码:
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); } }
如果我需要发布更多,我会的.但真的很多东西要看.我使用的所有代表分配的方法的返回类型具有返回类型“结论”< T>所以我可以有一个返回对象以及一个错误,如果发生.上面代码中的函数返回结束语< BaseFunction>,但是返回被转换成对象Addend< T>如果是一个数字.如果它是返回字符串或bool或其他类型的另一种类型的函数的一部分,则将其转换为不同类型的类.在数值计算结束之后,返回值将与结束语< int>或结论< double> ;.所以添加int和double到IConcludable接口是我想要做的. 更好地解释应用程序 我正在编写一个C#控制台应用程序.它需要用户的输入,并写出答案.输入类似于Excel公式:Sum(5,15,Average(2,3),5)或Concatenate(“5 5 =”,Text(Sum(5,5))).输入字符串经过验证,解析,并返回结果.
解决方法
根据要求,我想解释一下我最后一个答案.
要求
>结论需要支持值类型和参考类型
>通用
>值类型:所有数值数据类型(int,short,long等),boolean,char,date ….
>参考类型:字符串和用户定义的类(在OP的样例中,IConcludable)
解:
>引入接受Object作为通用输入的基类(AbstractConclusion)
>将逻辑移动到基类以便重用
>引入两个新的具体实现,它们接受struct和IConcluable(可以为ex:string添加更多的实现)
>继承的类能够实现基类的所有方法
原始答案:
您可以将逻辑放在AbstractConclusion类中,并具有两个实现(结论接受接受结构数据类型的IConcludeable和PrimitiveConclusion)
参见下面的代码示例:
void Main() { PrimitiveConclusion<int> primitiveConclusion = new PrimitiveConclusion<int>(1); Conclusion<ParseResult> parseResultConclusion = new Conclusion<ParseResult>(new ParseResult {}); Console.WriteLine($"{primitiveConclusion.Result.GetType()}"); Console.WriteLine($"{parseResultConclusion.Result.GetType()}"); } public class TestClass { public Conclusion<ParseResult> ParseInput(string input) { return new Conclusion<ParseResult>(null); } } public interface IConcludable { } public abstract class AbstractConclusion<T> { public AbstractConclusion(T t) { IsSuccessful = t != null; Result = t; } public bool IsSuccessful; public T Result; } public class Conclusion<T> : AbstractConclusion<T> where T : IConcludable { public Conclusion(T t) : base(t) { } } public class PrimitiveConclusion<T> : AbstractConclusion<T> where T : struct { public PrimitiveConclusion(T t) : base(t) { } } public class ParseResult : IConcludable { }