我想为一些内置类型添加一个接口。我有一个界面IConcludable
,我将其用作Conclusion<T>
的约束。我不知道如何处理这个问题,或者甚至是否可能。
基本布局
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
等。我想使用{ {1}}作为返回,因为我有一个类在输入字符串无效时处理错误报告:
Conclusion<T>
研究
我研究了约束。
似乎约束只是加在一起,所以包括我需要的每个内置类型的接口都需要定义一大堆与我的if (conclusion.ReturnObject is ErrorReport)
{
ErrorManager errorManager = new ErrorManager();
errorManager.Resolve(conclusion);
}
结构没有任何关系的方法。
扩展方法
这些实际上改变了内置类型的行为。这不是我想要的,因为我的界面Conclusion
没有任何方法。
替换内置类型
不可能。我不需要改变这些类型的行为。我只是想为它添加一个空接口。
似乎没有任何关于向内置类型添加接口的信息。我不确定“继承”是否会被引用。这可能吗?
修改
对结论
的更好解释我在大多数方法中使用结论struct作为返回对象。这是因为我正在使用代表。请参阅以下对象的实际代码:
IConcludable
如果我需要发布更多信息,我会的。但看起来真的很多。我使用的所有委托分配的方法的返回类型的返回类型为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);
}
}
,这样我就可以有一个返回对象以及一个错误(如果有)。上面代码中的函数返回Conclusion<T>
,但如果它是一个数字,则该返回将转换为对象Conclusion<BaseFunction>
。如果它是另一种类型的函数的一部分,它返回Addend<T>
或string
或其他类型,则会将其转换为不同类型的类。在数值计算结束时,返回值将类似于bool
或Conclusion<int>
。因此,我正在尝试将Conclusion<double>
和int
添加到double
界面。
更好地解释应用程序
我正在编写一个C#控制台应用程序。它接受用户的输入,并写下答案。输入类似于Excel公式:IConcludable
或Sum(5, 15, Average(2, 3), 5)
。输入字符串经过验证,解析并返回结果。
答案 0 :(得分:1)
更新(添加更多解释)
根据要求,我想解释一下我的最后答案。
要求的
Conclusion
需要支持值类型和引用类型 IConcludable
)解决方案:
AbstractConclusion
作为通用输入的基类(Object
)struct
和IConcluable
的新具体实现(能够添加更多实现,例如:string)原始答案:
您可以将逻辑放在AbstractConclusion
类中,并有两个实现(Conclusion
接受IConcludeable
和PrimitiveConclusion
接受struct
数据类型)
请参阅下面的代码示例:
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 { }
答案 1 :(得分:0)
使用where T : IConcludable
泛型类型约束,您无法将int
作为泛型参数传递。而且也没有办法将接口附加到基本类型。
您可以采取一些解决方法来执行此操作。您可以将Conclusion
的主要逻辑放入基础抽象类并从中继承,将Conclusion
重构为class
(因为struct
不支持继承)并创建类
public class Conclusion<T> : BaseConclusion
where T : IConcludable
和
public class PrimitiveConclusion<T> : BaseConclusion
where T : struct
并且您还应该为string
创建另一个类,因为string
不是结构而不是实现IConcludable
据我所知,没有其他方法可以将不同类型作为泛型参数传递。
此外,您可以创建包装结构,而不是为内置类型创建Conclusion
类,它将实现IConcludable
。并与它达成协议
public struct Wrapper<T> : IConcludable
{
public T Value { get; set; }
}