Static extension methods
Possible Duplicate:
Can I add extension methods to an existing static class?
有没有任何方法可以将静态扩展方法添加到类中?
具体来说,我想重载boolean.parse以允许int参数。
- 怎么可能是复制品?这需要将一个行为类似于静态(类)方法的扩展方法添加到一个可以具有布尔实例的类中,而另一个问题则询问如何将扩展方法添加到静态类中。
- 如果C支持诸如"public static dependencyproperty register(static dependencyproperty x,string name,type propertytype,type ownertype,frameworkpropertymetadata typemetadata)"之类的语法,那就更好了,这样我就可以在Silverlight中使用它来实现与WPF语法的兼容性(包装dr.wpf对dependency的值强制的实现)。NCyType)。注意"static dependencyproperty"参数而不是"this dependencyproperty"参数(或者,它们可以使用其他关键字,如type或type of,而不是static)
- 提供字符串时,Enum.Parse也有同样的问题。遗憾的是,扩展字符串不像扩展int那么明显。C缺少语法!
- 我认为这可以通过即将发布的C规格中的形状来实现。
简而言之,不,你不能。
答案很长,扩展方法只是语法上的糖分。IE:
如果您对字符串有一个扩展方法,那么让我们假设:
1 2 3 4
| public static string SomeStringExtension(this string s)
{
//whatever..
} |
当你称之为:
1
| myString.SomeStringExtension(); |
编译器只是将其转换为:
1
| ExtensionClass.SomeStringExtension(myString); |
因此,正如您所看到的,对于静态方法,没有办法做到这一点。
另外一件事我才明白:能够在现有类上添加静态方法的真正意义是什么?您可以只拥有自己的助手类来做同样的事情,所以能够做的真正好处是:
VS
不会给桌子带来太多…
- 在现有类上添加静态方法的真正意义是什么?在很多情况下,我都想反复这样做。我的理由是:我想扩展String.Reconvert作为一种扩展方法。我可以写Helper.ReconvertString,但是使用Visual Studio和Auto-Complete,我的同事不会看Helper的下面。他们会找一个String方法,而不是找一个,可能去重新发明轮子。
- 我完全不同意,它的好处与实例扩展方法提供的好处相同。我也可以使用助手类来实现与普通扩展方法相同的目的,但是为什么当扩展方法更适合使用时我应该这样做呢?无论是实例还是静态的,句法糖都是有用的。
- 我认为他们会带来和语法糖一样多的东西。它是关于可访问性和你期望它们在流行类中出现的地方,而不是在晦涩的助手中。例如,像datetime.fromnanoseconds或datetime.fromsecondsinceepoch这样的扩展方法很有用。这些方法作为实例方法没有意义,因为它们本质上是构造函数,但是作为静态扩展方法很容易找到。原因是框架类只是不完整的,而扩展方法是完成它们的一种变通方法。
- @Triynko是对的。在上面的示例中,helper类在哪里,是什么?如何知道在哪里找到它,它在什么名称空间中?出于这些原因,扩展出现在您期望的地方,是一个有用的特性。
- 您使用string.Join方法而不是框架中单独的StringHelpers类是有原因的。不过,我讨厌期望有一个扩展方法,必须寻找合适的名称空间来添加它。至少在类中,我可以右键单击并解析添加using。
- 我认为这个答案可以被编辑成"不",因为这只是语言设计的问题。答案的其余部分没有显示在语言中实现静态扩展方法时有任何冲突的内容。
- 例如,现在我正在为控制台编写助手方法,以便更容易地输出颜色和更改光标位置,这样我就可以轻松地进行实时更新,而无需编写额外的行,并且在不"获取当前颜色/设置新颜色/写入输出/将颜色设置回原始颜色"的情况下以特定颜色输出某些内容。能够将它们添加到控制台中是很好的,但我可能会在类中重新实现写操作,以便相同的类可以用于所有输出。
- 我可以想到一个很好的例子,在这里您需要静态扩展方法。即使是Int32类也提供Parse(String)、Parse(String,?IFormatProvider)、Parse(String,?NumberStyles)、Parse(String,?NumberStyles,?IFormatProvider)过载,但Boolean类只提供Parse(String)。即使只是一个Bool.Parse(String,?IFormatProvider)重载,这样您就可以从其他语言中转换真/假值,这难道不是非常好吗?例如,cierto/falso(西班牙语)、vrai/faux(法语)和Правда/_о_(俄语)?
- 我不反对静态扩展,但您可能不想扩展一个公共的clr类的一个原因是,虽然它使扩展很容易找到,但它可能会建议开发人员扩展实际上是原始类的一部分。开发人员可能会尝试在另一个项目上使用扩展,然后困惑地发现它找不到。可能是秋千和环形交叉。
- StringExtensions.Reconvert(...)--bam,以一种有意义的方式解决了这个问题,它可读、清晰、合理,并且与intellisense很好地配合。它还允许您在一个类上同时放置实例扩展方法和静态扩展方法。
- @很明显,你还没有读过这个问题下面的评论:)
- @我写的书信集,因此我的建议在整个项目中都是有意义的标准化。只需在规范/指南中包含静态扩展方法类始终以*Extensions的形式存在。它也比Helpers简单得多,在某种程度上它可以被看作是一种完全不同的方法--当你在String上寻找一个静态方法时,你将首先输入Str...,这时StringExtensions静态类应该已经在建议的自动完成词列表中,它的名字明显地表明表明它的意图。
- @约翰,好吧,现在我明白你的理由了。事实上,这可能是迄今为止最好的解决方案。静态扩展在C中实现。
- 扩展方法要求此参数为非空。解决此问题的方法是编写一个静态方法,该方法可以使任何或所有参数为空,而不引发异常。我不拥有hashset的源代码,因此我无法修复unionwith()的这个缺点。如果我能修复它,我会写一个静态扩展方法。因为这是不可能的,所以我现在必须编写一个本地私有方法,并将其放到一个gist中。
specifically I want to overload Boolean.Parse to allow an int argument.
int的扩展是否有效?
1 2 3 4
| public static bool ToBoolean(this int source){
//do it
//return it
} |
然后你可以这样称呼它:
1 2 3
| int x = 1;
bool y=x.ToBoolean(); |
- +一是创造力。你没有回答他的问题,但我相信你找到了最优雅的解决方案。特别是考虑到字面上的"解析"意味着分析一个字符串:)(见定义)
- 别忘了,int是一个值类型。您需要使用@bsneeze y=x.ToBoolean()编写的格式,因为在值类型的扩展方法中,值不是通过引用传递的。
看起来你做不到。关于它的讨论见这里
不过,我很想被证明是错的。
可以向int添加扩展方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public static class IntExtensions
{
public static bool Parse(this int value)
{
if (value == 0)
{
return true;
}
else
{
return false;
}
}
public static bool? Parse2(this int value)
{
if (value == 0)
{
return true;
}
if (value == 1)
{
return false;
}
return null;
}
} |
像这样使用
1 2 3 4 5 6
| bool bool1 = 0.Parse();
bool bool2 = 1.Parse();
bool? bool3 = 0.Parse2();
bool? bool4 = 1.Parse2();
bool? bool5 = 3.Parse2(); |
- 这不能回答问题。这只演示了一个在int的实例上调用的普通扩展方法,在本例中是0、1、2或3。int文字与变量一样是一个实例。
- 另外,不要这样做。曾经。1.Parse()和"My String" ÷ 6一样毫无意义。你的代码应该是清晰的,别人可以理解的。"parse"就是按照上面提到的@tsemer"分析字符串"。
不,但是你可以有这样的东西:
1 2
| bool b;
b = b.YourExtensionMethod(); |