让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在Codeplex上建立了一个名为extensionoverflow的开源项目。
请将您的回答标记为接受,以便将代码放入Codeplex项目。
请张贴完整的源代码,而不是一个链接。
Codeplex上新闻:
24.08.2010 Codeplex页面现在在这里:http://extensionoverflow.codeplex.com/
11.11.2008 XmlSerialize / XmlDeserialize现在是实现和单元测试。
11.11.2008仍有发展空间。;-)现在就加入!
11.11.2008第三位贡献者加入了ExtensionOverflow,欢迎加入BKristensen
11.11.2008 FormatWith现在是实现和单元测试。
09.11.2008第二个贡献者加入ExtensionOverflow。欢迎来到chakrit。
我们需要更多的开发人员。: -)
09.11.2008 ThrowIfArgumentIsNull现已在Codeplex上实现和单元测试。
下面是一个扩展方法,它适应Rick Strahl的代码(以及注释),使您不必在每次将字节数组或文本文件转换为字符串时猜测或阅读其字节顺序标记。
这个代码片段允许你简单地做:
byte[] buffer = File.ReadAllBytes(@"C:\file.txt");
string content = buffer.GetString();
如果你发现任何错误,请添加到评论中。请随意将它包含在Codeplex项目中。
public static class Extensions
{
/// <summary>
/// Converts a byte array to a string, using its byte order mark to convert it to the right encoding.
/// Original article: http://www.west-wind.com/WebLog/posts/197245.aspx
/// </summary>
/// <param name="buffer">An array of bytes to convert</param>
/// <returns>The byte as a string.</returns>
public static string GetString(this byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
return "";
// Ansi as default
Encoding encoding = Encoding.Default;
/*
EF BB BF UTF-8
FF FE UTF-16 little endian
FE FF UTF-16 big endian
FF FE 00 00 UTF-32, little endian
00 00 FE FF UTF-32, big-endian
*/
if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
encoding = Encoding.UTF8;
else if (buffer[0] == 0xfe && buffer[1] == 0xff)
encoding = Encoding.Unicode;
else if (buffer[0] == 0xfe && buffer[1] == 0xff)
encoding = Encoding.BigEndianUnicode; // utf-16be
else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
encoding = Encoding.UTF32;
else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
encoding = Encoding.UTF7;
using (MemoryStream stream = new MemoryStream())
{
stream.Write(buffer, 0, buffer.Length);
stream.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream, encoding))
{
return reader.ReadToEnd();
}
}
}
}
我喜欢下面这些方法来处理带有Flags属性集的枚举:
public static bool AnyOf(this object mask, object flags)
{
return ((int)mask & (int)flags) != 0;
}
public static bool AllOf(this object mask, object flags)
{
return ((int)mask & (int)flags) == (int)flags;
}
public static object SetOn(this object mask, object flags)
{
return (int)mask | (int)flags;
}
etc.
使用示例:
var options = SomeOptions.OptionA;
options = options.SetOn(OptionB);
options = options.SetOn(OptionC);
if (options.AnyOf(SomeOptions.OptionA | SomeOptions.OptionB))
{
etc.
原始方法来自本文:http://www.codeproject.com/KB/cs/masksandflags.aspx?display=Print
我只是把它们转换成扩展方法。
但它们的一个问题是对象类型的参数,这意味着所有对象最终都被这些方法扩展,而理想情况下,它们应该只应用于枚举。
更新
根据评论,你可以绕过“签名污染”,以牺牲性能为代价,如下所示:
public static bool AnyOf(this Enum mask, object flags)
{
return (Convert.ToInt642(mask) & (int)flags) != 0;
}
在我的MiscUtil项目中有各种扩展方法(完整的源代码在那里可用-我不打算在这里重复它)。我最喜欢的,其中一些涉及其他类(如范围):
日期和时间——主要用于单元测试。我不确定我会在生产中使用它们:)
var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();
范围和步进——非常感谢Marc Gravell的运算符使这成为可能:
var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());
比较:
var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();
参数检查:
x.ThrowIfNull("x");
LINQ to XML应用于匿名类型(或其他具有适当属性的类型):
// <Name>Jon</Name><Age>32</Age>
new { Name="Jon", Age=32}.ToXElements();
// Name="Jon" Age="32" (as XAttributes, obviously)
new { Name="Jon", Age=32}.ToXAttributes()
Push LINQ -在这里解释太长了,但是可以搜索一下。
这是一个位图扩展,可以将位图转换为灰度;
public static Bitmap GrayScale(this Bitmap bitmap)
{
Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height);
Graphics g = Graphics.FromImage(newBitmap);
//the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(new float[][] {
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, attributes);
g.Dispose();
return newBitmap;
}
示例用法:
Bitmap grayscaled = bitmap.GrayScale()
我的转换扩展,允许你做:
int i = myString.To<int>();
这是在TheSoftwareJedi.com上发布的
public static T To<T>(this IConvertible obj)
{
return (T)Convert.ChangeType(obj, typeof(T));
}
public static T ToOrDefault<T>
(this IConvertible obj)
{
try
{
return To<T>(obj);
}
catch
{
return default(T);
}
}
public static bool ToOrDefault<T>
(this IConvertible obj,
out T newObj)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = default(T);
return false;
}
}
public static T ToOrOther<T>
(this IConvertible obj,
T other)
{
try
{
return To<T>obj);
}
catch
{
return other;
}
}
public static bool ToOrOther<T>
(this IConvertible obj,
out T newObj,
T other)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = other;
return false;
}
}
public static T ToOrNull<T>
(this IConvertible obj)
where T : class
{
try
{
return To<T>(obj);
}
catch
{
return null;
}
}
public static bool ToOrNull<T>
(this IConvertible obj,
out T newObj)
where T : class
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = null;
return false;
}
}
您可以在失败时请求default(调用空白构造函数或“0”作为数字),指定一个“default”值(我称之为“other”),或请求null(其中T: class)。我还提供了两个静默异常模型和一个典型的TryParse模型,该模型返回一个bool值,指示所采取的操作,一个out参数保存新值。
我们的代码可以这样做
int i = myString.To<int>();
string a = myInt.ToOrDefault<string>();
//note type inference
DateTime d = myString.ToOrOther(DateTime.MAX_VALUE);
double d;
//note type inference
bool didItGiveDefault = myString.ToOrDefault(out d);
string s = myDateTime.ToOrNull<string>();
我不能让Nullable类型非常干净地滚入整个东西。我试了大约20分钟才认输。