c# - 重写 C# 中的隐式运算符

标签 c# operator-overloading overriding

我使用一个框架,它公开了一个名为Value的抽象类。通过运算符重载,几乎可以将任何内容分配给此类的对象,并且它的工作方式就像一个魅力:

Value a = "hello";
Value b = 1;
Value c = true;
Value d = 3.14;

(请注意,这是创建 Value 实例的唯一方法。除了重载运算符之外,没有公共(public)/ protected 方法可以将值分配给实例。)

现在,我想重写隐式运算符 Value(string input) 函数,以便它在分配任何字符串之前对其进行 XML 清理。

我尝试继承此类并重写运算符,但尚未找到将清理后的字符串输入基类的运算符函数的方法。以下显然不起作用:

public override static implicit operator XmlValue(string input)
{
    string output = sanitize(input);
    XmlValue rv = null;
    ((Value)rv) = output; // this is not possible
    return rv;
}

有办法实现这一点吗?或者,我是否可能过度思考这个问题,对于我想做的事情是否有更好的解决方案?无论如何,我希望避免在将每个字符串分配给 Value 之前必须对其进行清理;这太容易出错了。

仅供引用:Value 类是 Cottle framework 的一部分.

最佳答案

重要的一点是您不能“覆盖”运算符,因为它们是静态的。您可以在派生类中定义一个新运算符,然后使用派生类型的变量进行赋值(以便编译器知道它需要调用派生类的运算符)。

看这个例子:

using System;

class Value {
    public string StringValue {
        get;
        private set;
    }
    protected Value(string str) {
        StringValue = str;
    }
    public static implicit operator Value(string input) {
        return new Value(input);
    }
}

class XmlValue : Value {
    protected XmlValue(string str) : base(str) {
    }
    public static implicit operator XmlValue(string input) {
        // using "ToUpperInvariant" instead of sanitize
        return new XmlValue(input.ToUpperInvariant());
    }
}

class Program {
    static void Main(string[] args) {
        Value v1 = "test";
        Console.WriteLine(v1.StringValue); // "test"
        XmlValue v2 = "test";
        Console.WriteLine(v2.StringValue); // "TEST"
    }
}

查看您的评论后,我认为下面的示例更符合您面临的实际情况。

但是,尽管这种运算符重载可能很有趣,但我认为在这种情况下,您绝对应该选择更简单且更具可读性的解决方案,即在分配之前清理每个输入。

using System;

abstract class Value {
    public string StringValue {
        get;
        protected set;
    }
    public static implicit operator Value(string input) {
        return new StringValue(input);
    }
}

class StringValue : Value {
    public StringValue(string str) {
        StringValue = str;
    }
}

class Xml {
    string _value;
    public Xml(string value) {
        _value = value;
    }
    public static implicit operator Xml(string input) {
        return new Xml(input.ToUpperInvariant());
    }
    public static implicit operator Value(Xml xml) {
        Value ret = xml._value;
        return ret;
    }
}

class Program {
    static void Main(string[] args) {
        // this works with the cast operators...
        Value v1 = (Xml)"test";
        Console.WriteLine(v1.StringValue); // "TEST"

        // ...but I would definitely go for this:
        Value v2 = sanitize("test");
    }
}

关于c# - 重写 C# 中的隐式运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46190907/

相关文章:

c# - 在 NancyFx 上下文中获取 Windows 用户

c# - 我应该如何在不重复测试的情况下测试将其大部分行为委托(delegate)给同一类中的另一个方法的方法?

Django Formset 覆盖为表以显示为网格

c++11 - C++11 中的最终非多态类

c# - 如何覆盖 ToString() 并实现泛型?

c# - IEnumerable<T> 到 IDictionary<U, IEnumerable<T>>

c# - Entity Framework 添加许多实体,嵌套属性已经存在

c++ - 将 Boost 参数与 operator() 一起使用

c++ - AVL 树中的比较由指向对象的指针组成

c++ - 运算符和返回类型是什么意思?