在int上使用扩展方法

时间:2011-07-11 21:41:16

标签: c# extension-methods

我正在阅读有关扩展方法的内容,并对它们进行修改 看看它们是如何工作的,我试过这个:

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。但相反,编译器甚至不喜欢 后来的代码,并将红色波浪线放在两个下面,并说“预期类型”。 为什么不能这样做?

7 个答案:

答案 0 :(得分:17)

非常聪明!一个不错的尝试,但遗憾的是我们没有实现“扩展所有内容”,只是扩展方法。

我们考虑过实现扩展属性,扩展操作符,扩展事件,扩展构造函数,扩展接口,你可以命名,但是大多数都没有引人注目,无法进入C#4或即将推出的C#版本。我们为你提到的那种东西设计了一种语法。我们在扩展属性方面做得更远;我们几乎将扩展属性添加到C#4中,但最终没有成功。悲伤的故事就在这里。

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

所以,长话短说,没有这样的功能,但我们会考虑将其用于该语言的假设未来版本。

如果您真的喜欢非零意味着真实的复古C约定,您当然可以在ToBool()上制作“int”扩展方法。< / p>

答案 1 :(得分:13)

扩展方法就是那种方法 您无法创建扩展操作符或属性。

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

答案 2 :(得分:6)

正如其他人所说,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);
    }
}

答案 3 :(得分:2)

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

基本上,你想做的事情无法完成。

引入新运算符的唯一方法是将它们放在一个涉及的类型中。对于二元运算符,您可以将它们放在您自己的类型中,前提是您的类型是两者之一,对于一元类型,您需要将运算符放在类型本身中。

由于您无法以任何方式扩展int,因此您无法做到。

答案 4 :(得分:2)

Console.WriteLine(5.doubleMe());

相当于

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

鉴于此,您可以看到为什么if ( 7 )不起作用。

扩展方法只不过是语法。

作为旁注,因为它是语法,您可以在null变量上调用扩展方法,因为它转换为普通的方法调用,并且方法可以采用null参数。

答案 5 :(得分:1)

不幸的是,你不能使用扩展方法来添加运算符,而C#中的隐式类型转换是作为运算符实现的。

答案 6 :(得分:0)

在第一个实例中,您正在编写扩展方法 - 例如扩展int数据类型的功能。在第二个代码集中,您尝试覆盖bool运算符。这是两件完全不同的事情。