有没有办法扩展内置类型以继承接口?

时间:2015-12-23 07:55:00

标签: c# inheritance built-in

我想为一些内置类型添加一个接口。我有一个界面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);
}

问题

当我获得最终值时,它是内置类型,如intdoublestringbool等。我想使用{ {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或其他类型,则会将其转换为不同类型的类。在数值计算结束时,返回值将类似于boolConclusion<int>。因此,我正在尝试将Conclusion<double>int添加到double界面。

更好地解释应用程序

我正在编写一个C#控制台应用程序。它接受用户的输入,并写下答案。输入类似于Excel公式:IConcludableSum(5, 15, Average(2, 3), 5)。输入字符串经过验证,解析并返回结果。

2 个答案:

答案 0 :(得分:1)

更新(添加更多解释)

根据要求,我想解释一下我的最后答案。

要求

  • Conclusion需要支持值类型和引用类型
  • 通用
  • 值类型:所有数值数据类型(int,short,long等),boolean,char,date ....
  • 参考类型:字符串和用户定义的类(在OP的示例中, IConcludable

解决方案:

  • 介绍接受AbstractConclusion作为通用输入的基类(Object
  • 将逻辑移至基类以供重用
  • 介绍两个接受structIConcluable的新具体实现(能够添加更多实现,例如:string)
  • 继承的类可以使用基类的所有方法

原始答案:

您可以将逻辑放在AbstractConclusion类中,并有两个实现(Conclusion接受IConcludeablePrimitiveConclusion接受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; }
}