一位同事今天问我如何为一个系列添加一个范围.他有一个继承自的课程Collection<T>.这种类型的get-only属性已包含一些项目.他想将另一个集合中的项目添加到属性集合中.他怎么能以C#3友好的方式这样做呢?(注意关于get-only属性的约束,这会阻止像执行Union和重新分配这样的解决方案.)
当然,与物业的foreach.添加将工作.但是A List<T>风格的AddRange会更加优雅.
编写扩展方法很容易:
public static class CollectionHelpers
{
public static void AddRange<T>(this ICollection<T> destination,
IEnumerable<T> source)
{
foreach (T item in source)
{
destination.Add(item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我感觉我正在重新发明轮子.我没有发现任何类似System.Linq或morelinq.
糟糕的设计?只需致电添加?缺少明显的?
在某些情况下,我想要使用扩展方法覆盖类中的方法.有没有办法在C#中做到这一点?
例如:
public static class StringExtension
{
public static int GetHashCode(this string inStr)
{
return MyHash(inStr);
}
}
Run Code Online (Sandbox Code Playgroud)
在那里我一直想做到这一点的情况是能够将一个字符串的哈希存储到数据库中,并有相同的值由所有使用String类的哈希值(即词典等)由于类使用内置的.Net哈希算法不能保证从一个版本的Framework到下一个版本兼容,我想用我自己的版本替换它.
还有其他情况我遇到了我想用扩展方法覆盖类方法的地方,所以它不仅仅特定于字符串类或GetHashCode方法.
我知道我可以通过子类化现有的类来做到这一点但是在很多情况下能够使用扩展来做它会很方便.
我安装了Active Support 3.0.3,使用Ruby 1.8.7安装了Rails 3.0.3.
当我尝试使用时,1.week.ago我得到了
NoMethodError: undefined method 'week' for 1:Fixnum
from (irb):2
Run Code Online (Sandbox Code Playgroud)
其他核心扩展似乎有效.我在一个朋友的计算机上尝试过(同样的安装规范和旧版本),结果相同.
是什么赋予了?
所有这些都在IRB中.
可以将扩展方法应用于类吗?
例如,扩展DateTime以包含可以调用的Tomorrow()方法,如:
DateTime.Tomorrow();
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用
static DateTime Tomorrow(this Datetime value) { //... }
Run Code Online (Sandbox Code Playgroud)
要么
public static MyClass {
public static Tomorrow() { //... }
}
Run Code Online (Sandbox Code Playgroud)
对于类似的结果,但我如何扩展DateTime以便我可以调用DateTime.Tomorrow?
我在MSDN的Linq示例中找到了一个名为Fold()的简洁方法,我想使用它.他们的例子:
double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
double product =
doubles.Fold((runningProduct, nextFactor) => runningProduct * nextFactor);
Run Code Online (Sandbox Code Playgroud)
不幸的是,无论是在他们的示例中还是在我自己的代码中,我都无法进行编译,而且我在MSDN中找不到任何其他地方(如Enumerable或Array扩展方法).我得到的错误是一个普通的"不知道任何关于那个"的错误:
error CS1061: 'System.Array' does not contain a definition for 'Fold' and no
extension method 'Fold' accepting a first argument of type 'System.Array' could
be found (are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)
我正在使用其他我认为来自Linq的方法(比如Select()和Where()),我正在"使用System.Linq",所以我认为一切都好.
这种方法确实存在于C#3.5中,如果是这样,我做错了什么?
大家问候......我需要Trim一个String.但我想删除String本身内的所有重复空格,不仅仅是在结尾或开头.我可以通过以下方法来实现:
public static string ConvertWhitespacesToSingleSpaces(string value)
{
value = Regex.Replace(value, @"\s+", " ");
}
Run Code Online (Sandbox Code Playgroud)
我从这里得到了什么.但我希望在String.Trim()自身内部调用这段代码,所以我认为我需要扩展或重载或覆盖该Trim方法......有没有办法做到这一点?
提前致谢.
C#的"非信徒"问我扩展方法的目的是什么.我解释说,然后您可以向已定义的对象添加新方法,尤其是当您不拥有/控制原始对象的源时.
他提出"为什么不在自己的课堂上添加一种方法?" 我们一直在四处走动(以一种很好的方式).我的一般回答是,它是工具带中的另一个工具,他的回答是它是一种无用的工具浪费......但我认为我会得到一个更"开明"的答案.
有哪些场景你使用了你不能(或不应该)使用的方法添加到你自己的类上的扩展方法?
我正在编写一个依赖于扩展方法结果的测试,但我不希望该扩展方法的未来失败会破坏此测试.模拟这个结果似乎是显而易见的选择,但是Moq似乎没有提供一种覆盖静态方法的方法(扩展方法的要求).与Moq.Protected和Moq.Stub有类似的想法,但它们似乎没有为这种情况提供任何东西.我错过了什么或者我应该以不同的方式去做这件事吗?
这是一个简单的例子,通常会对"不可覆盖的成员的无效期望"失败.这是需要模拟扩展方法的一个不好的例子,但它应该这样做.
public class SomeType {
int Id { get; set; }
}
var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
.Returns(new SomeType { Id = 5 });
Run Code Online (Sandbox Code Playgroud)
至于任何可能建议我使用Isolator的TypeMock迷们:我很欣赏这项努力,因为看起来TypeMock可能会被蒙住眼睛和醉酒,但我们的预算不会很快增加.
我原本想知道如何制作这样的东西
UIColor.myCustomGreen
Run Code Online (Sandbox Code Playgroud)
这样我就可以定义自己的颜色并在整个应用程序中使用它们.
之前我曾经研究过扩展,我认为我可以用它们来解决我的问题,但我不记得究竟如何设置扩展.在撰写本文时,在Google上搜索"Swift扩展"会导致文档,几个长篇教程以及一个相当无用的Stack Overflow 问题.
所以答案就在那里,但需要深入研究文档和教程.我决定写这个问题和以下答案,为Stack Overflow添加一些更好的搜索关键字,并快速回顾一下如何设置扩展.
具体来说我想知道: