[英]Overriding implicit operators in C#
I use a framework which exposes an abstract class called Value
. 我使用的框架公开了一个名为
Value
的抽象类。 Through operator overloading, it's possible to assign almost anything to this class's objects, and it works like a charm: 通过运算符重载,几乎可以将任何东西分配给此类的对象,并且它的工作原理就像一个魅力:
Value a = "hello";
Value b = 1;
Value c = true;
Value d = 3.14;
(Note that this is the only way to create instances of Value
. There are no public/protected ways to assign values to instances, other than the overloaded operators.) (请注意,这是创建
Value
实例的唯一方法。除了重载的运算符外,没有公共/受保护的方法将值分配给实例。)
Right now, I want to override the implicit operator Value(string input)
function, so that it XML-sanitizes any string before assigning it. 现在,我想重写
implicit operator Value(string input)
函数,以便它在分配字符串之前先对其进行XML消毒。
I have tried inheriting this class and overriding the operator, but have not found a way to feed the sanitized string into the base class's operator function. 我曾尝试继承此类并覆盖运算符,但还没有找到将经过清理的字符串输入基类运算符的方法。 The following obviously doesn't work:
以下显然不起作用:
public override static implicit operator XmlValue(string input)
{
string output = sanitize(input);
XmlValue rv = null;
((Value)rv) = output; // this is not possible
return rv;
}
Is there a way to achieve this? 有没有办法做到这一点? Or alternatively, am I perhaps overthinking the problem and is there a better solution for what I want to do?
或者,也许我是想得太多了,是否有更好的解决方案? In any case, I'd like to avoid having to sanitize each and every string before assigning it to a
Value
; 无论如何,我都希望避免在将每个字符串分配给
Value
之前清理每个字符串; this would be way too error prone. 这太容易出错了。
FYI: the Value
class is part of the Cottle framework . 仅供参考:
Value
类是Cottle框架的一部分。
The important point is that you cannot "override" operators, because they are static. 重要的一点是您不能“覆盖”运算符,因为它们是静态的。 You can instead define a new operator in your derived class, then make the assignment using a variable of your derived type (so that the compiler knows that it needs to call the operator of the derived class).
您可以在派生类中定义一个新的运算符,然后使用派生类型的变量进行赋值(以便编译器知道它需要调用派生类的运算符)。
Look at this example: 看这个例子:
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"
}
}
After checking your comment , I think that the example below is more related to the real situation you are facing. 在检查您的评论之后 ,我认为下面的示例与您所面临的实际情况更加相关。
However, as fun as this operators overloading might be, I think that in this case you should definitely opt for the simpler and more readable solution of sanitizing every input before assignment. 但是,尽管这个运算符重载可能会很有趣,但我认为在这种情况下,您绝对应该选择一种更简单,更易读的解决方案,即在分配赋值之前对每个输入进行清理。
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");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.