在int上使用扩展方法

本文关键字:扩展 方法 int | 更新日期: 2023-09-27 18:01:42

我正在阅读有关扩展方法的内容,并尝试使用它们看看它们是如何工作的,我试着这样做:

namespace clunk {
    public static class oog {
        public static int doubleMe(this int x) {
            return 2 * x;
        }
    }
    class Program {
        static void Main() {
            Console.WriteLine(5.doubleMe());
        }
    }
}

,它按预期工作,成功地用doubleMe方法扩展int,输出10.

接下来,作为一个老C的家伙,我想知道我是否能做到这一点:

namespace clunk {
    public static class BoolLikeC {
        public static bool operator true(this int i)  { return i != 0; }
        public static bool operator false(this int i) { return i == 0; }
    }
    class Program {
        static void Main() {
            if ( 7 ) {
                Console.WriteLine("7 is so true");
            }
        }
    }
}

我认为如果前者能起作用,那么后者应该起作用,使在布尔上下文中使用的int将调用int的扩展方法,请查看7不等于0,返回true。但是,编译器甚至不喜欢在这两个字母下面画上红色的弯弯曲曲的线,并写着"预期输入"。为什么这行不通呢?

在int上使用扩展方法

很聪明!一个很好的尝试,但遗憾的是我们没有实现"扩展一切",只是扩展方法。

我们考虑过实现扩展属性、扩展操作符、扩展事件、扩展构造函数、扩展接口等等,但它们中的大多数都不够引人注目,无法纳入c# 4或即将发布的c#版本。我们已经为你提到的事情设计了语法。我们在可拓性上走得更远了;我们几乎在c# 4中加入了扩展属性,但最终没有成功。故事就在这里。

http://blogs.msdn.com/b/ericlippert/archive/2009/10/05/why-no-extension-properties.aspx

所以,长话短说,没有这样的功能,但我们会考虑在未来的语言版本中使用它。

你当然可以在int上做一个" ToBool() "扩展方法,如果你真的喜欢复古的C惯例非零意味着真

扩展方法就是那个方法。
不能创建扩展操作符或属性。

如果这是可能的,将导致非常难以阅读的代码。
如果您不熟悉代码库,几乎不可能弄清楚if (7)的含义。

正如其他人所说,c#中没有扩展操作符这种东西。

你所能得到的最接近的方法是在自定义的"桥接"类型上使用隐式转换操作符,但要冒着导致大量严重错误的风险:

// this works
BoolLikeC evil = 7;
if (evil) Console.WriteLine("7 is so true");
// and this works too
if ((BoolLikeC)7) Console.WriteLine("7 is so true");
// but this still won't work, thankfully
if (7) Console.WriteLine("7 is so true");
// and neither will this
if ((bool)7) Console.WriteLine("7 is so true");
// ...
public struct BoolLikeC
{
    private readonly int _value;
    public int Value { get { return _value; } }
    public BoolLikeC(int value)
    {
        _value = value;
    }
    public static implicit operator bool(BoolLikeC x)
    {
        return (x.Value != 0);
    }
    public static implicit operator BoolLikeC(int x)
    {
        return new BoolLikeC(x);
    }
}

遗憾的是,您不能通过扩展方法在类型上引入新的操作符或实现对现有操作符的支持。

基本上,你想做的事是做不到的。

引入新操作符的唯一方法是将它们放入所涉及的类型之一。对于二元操作符,只要您的类型是这两种类型之一,就可以将其放入自己的类型中;对于一元类型,则需要将操作符放入类型本身中。

由于您不能以任何方式扩展int,因此您不能这样做

Console.WriteLine(5.doubleMe());

等价于

Console.WriteLine(oog.doubleMe(5));

既然如此,你就可以明白为什么if ( 7 )不能工作了。

扩展方法只不过是语法。

作为旁注,由于它是语法,您可以在null变量上调用扩展方法,因为它转换为正常的方法调用,并且方法可以接受空参数。

遗憾的是,您不能使用扩展方法添加操作符,c#中的隐式类型转换是作为操作符实现的。

在第一个实例中,你正在编写一个扩展方法-例如扩展int数据类型的功能。在第二个代码集中,您试图覆盖bool操作符。这完全是两码事