2010-04-06 133 views
7

天儿真好配合 -C#字符串运算符重载

什么是正确的方式(不包括它是否是可取的说法)超载字符串运算<,>,< =和> =?

我试过五种方法到星期天,我得到各种错误 - 我最好的办法是声明一个部分类和从那里重载,但它不会因为某些原因。

namespace System 
{ 
    public partial class String 
    { 
     public static Boolean operator <(String a, String b) 
     { 
      return a.CompareTo(b) < 0; 
     } 

     public static Boolean operator >(String a, String b) 
     { 
      return a.CompareTo(b) > 0; 
     } 
    } 

}

+0

FYI:部分类需要驻留在同一组件(项目)。 – 2014-04-03 06:34:17

+0

这些运算符已经定义了字符串,因此重新定义它们是没有意义的。如果可能的话,它可能会破坏很多代码。 – Phil1970 2016-06-03 23:00:29

回答

16

字符串是一个密封的类。您不能继承它,并且没有String的原始源,您无法编译它的部分类。即使你已经掌握了源代码(可以通过Reflector或通过Visual Studio符号下载),你仍然会遇到问题,因为它是运行时的头等公民。

你真的需要<和>作为字符串运算符吗?如果是这样......为什么不使用extension methods

public static bool IsLessThan(this string a, string b) 
{ 
    return a.CompareTo(b) < 0; 
} 

public static bool IsGreaterThan(this string a, string b) 
{ 
    return a.CompareTo(b) > 0; 
} 


// elsewhere... 
foo.IsLessThan(bar); // equivalent to foo < bar 
+4

即使他能继承它,只知道是他继承型**的和继承的类型引用的情况下**将能够使用备用的运营商。由于运算符不是多态的(它们被重载,没有被覆盖),即使将子类型引用为“字符串”也会消除替代运算符的功能。 – 2010-04-06 19:27:14

+0

@亚当罗宾逊:确切地说。底线:@ScottSEA根本无法做他想做的事。 – Randolpho 2010-04-06 19:34:14

+1

我知道你的帖子不是关于扩展方法,但它可能是有用的提供一个链接。对于新来的C#人来说,它看起来像被称为错误的。 http://msdn.microsoft.com/en-ca/library/vstudio/bb383977.aspx – jgreep 2013-01-15 17:46:44

5

你的意思是System.String类?这在C#中是不可能的。您不能将扩展操作符添加到现有的类。这是一个很多要求功能,但。

10

简单的答案是,你不能;没有办法为另一个班级修改操作员。部分类只允许在同一程序集中定义的所有文件和中声明的声明为partial

3
  • 你不能有串部分类,因为String类本身不部分,因此不会与你的部分类的工作。

  • 字符串是密封的,所以你可以继承它,然后重载操作符。

总之,唉,你不能做你做的事情。

不知道你想要做什么,我不能建议一个好的选择。但是,看看extension methods,这往往是有利于情况。撇开无论你是否应该 :),你可以添加到字符串类的方法称为IsGreaterThan并返回true或false,但是你希望。这是很好的,因为您可以给扩展方法一个名称,使其意义明确,使现有的操作符保持完整(无论如何您都没有选择),并且允许快速/简单的代码。

1

您不能直接重载> =和< =运算符,但可以通过分别重载>和==来实现相同的结果。

你的代码似乎对我来说是正确的,只是你错过了==的重载。

似乎我错了,但是,你总是可以回到反思。我认为如果你做一些挖掘和黑客攻击,你可以使用反射来扩展类,因为反射允许在运行时添加函数或交换函数体。

无论是可取的,好的做法,我表示怀疑。为什么课堂被封闭是有原因的。做一些我提到的事情可能会导致某些情况下的未定义行为,这是由于.net框架对字符串所做的一些假设。机会很大,字符串类将在内部崩溃。

+1

因为练习不好而陷入困境? :p – Henri 2010-04-06 19:29:23

15

没有办法更换任何内建有自己的编译器的行为。您无法覆盖现有的内置运算符以进行比较,转换,算术运算等等。这是设计的;这是为了让别人可以读取你的代码,并知道int x = M(); int y = x + 2;做整数算术,而不是格式化你的硬盘。

你能解释一下你为什么要这么做?也许有更好的方法去做你想做的事。

+0

感谢您的回答。作为一个敏锐的坚持的设计决定,它可以解释为什么自定义字符串运算符在十年前不可能实现,而且至今还没有。 – 2013-09-29 14:42:39

+0

我要寻找的,而代表 'String.Concat(Enumerable.Repeat( “你好”,4))' 作为 ' “你好” * 4' 是否有人知道这是可能的以任何方式? – 2016-08-29 15:51:09

+1

@AlexeyKhoroshikh:不。没有可以定义该运算符的类型。 – 2016-08-29 15:58:49