让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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上实现和单元测试。
下面是我用来减少提取单个属性的一些方法:
public static T GetAttribute<T>(this ICustomAttributeProvider provider, bool inherit = false, int index = 0) where T : Attribute
{
return provider.GetAttribute(typeof(T), inherit, index) as T;
}
public static Attribute GetAttribute(this ICustomAttributeProvider provider, Type type, bool inherit = false, int index = 0)
{
bool exists = provider.IsDefined(type, inherit);
if (!exists)
{
return null;
}
object[] attributes = provider.GetCustomAttributes(type, inherit);
if (attributes != null && attributes.Length != 0)
{
return attributes[index] as Attribute;
}
else
{
return null;
}
}
用法(枚举描述hack的实现):
public static string GetDescription(this Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attribute = fieldInfo.GetAttribute<DescriptionAttribute>();
return attribute != null ? attribute.Description : null;
}
请随意将其包含在CodePlex项目中!
我使用这个扩展方法通常与匿名类型,以获得一个字典ala ruby
public static Dictionary<string, object> ToDictionary(this object o)
{
var dictionary = new Dictionary<string, object>();
foreach (var propertyInfo in o.GetType().GetProperties())
{
if (propertyInfo.GetIndexParameters().Length == 0)
{
dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(o, null));
}
}
return dictionary;
}
你可以使用它
var dummy = new { color = "#000000", width = "100%", id = "myid" };
Dictionary<string, object> dict = dummy.ToDictionary();
用扩展的方法
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
}
}
你可以做到的
dummy.ToDictionary().ForEach((p) => Console.Write("{0}='{1}' ", p.Key, p.Value));
输出
Color ='#000000' width='100%' id='myid'
public static class StringExtensions {
/// <summary>
/// Parses a string into an Enum
/// </summary>
/// <typeparam name="T">The type of the Enum</typeparam>
/// <param name="value">String value to parse</param>
/// <returns>The Enum corresponding to the stringExtensions</returns>
public static T EnumParse<T>(this string value) {
return StringExtensions.EnumParse<T>(value, false);
}
public static T EnumParse<T>(this string value, bool ignorecase) {
if (value == null) {
throw new ArgumentNullException("value");
}
value = value.Trim();
if (value.Length == 0) {
throw new ArgumentException("Must specify valid information for parsing in the string.", "value");
}
Type t = typeof(T);
if (!t.IsEnum) {
throw new ArgumentException("Type provided must be an Enum.", "T");
}
return (T)Enum.Parse(t, value, ignorecase);
}
}
将字符串解析为Enum很有用。
public enum TestEnum
{
Bar,
Test
}
public class Test
{
public void Test()
{
TestEnum foo = "Test".EnumParse<TestEnum>();
}
}
这要归功于斯科特·多尔曼
——编辑Codeplex项目——
我问过Scott Dorman,他是否介意我们在Codeplex项目中发布他的代码。我从他那里得到的回答是:
感谢你对SO帖子和CodePlex项目的提醒。我赞成你对这个问题的回答。是的,代码目前在CodeProject开放许可证(http://www.codeproject.com/info/cpol10.aspx)下有效地处于公共领域。
我没有问题,这被包括在CodePlex项目,如果你想把我添加到项目(用户名是sdorman),我会添加该方法加上一些额外的枚举助手方法。
通过操作系统文件系统信息比较文件/目录。这对于比较共享和本地文件非常有用。
用法:
DirectoryInfo dir = new DirectoryInfo(@"C:\test\myShareDir");
Console.WriteLine(dir.IsSameFileAs(@"\\myMachineName\myShareDir"));
FileInfo file = new FileInfo(@"C:\test\myShareDir\file.txt");
Console.WriteLine(file.IsSameFileAs(@"\\myMachineName\myShareDir\file.txt"));
代码:
public static class FileExtensions
{
struct BY_HANDLE_FILE_INFORMATION
{
public uint FileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
public uint VolumeSerialNumber;
public uint FileSizeHigh;
public uint FileSizeLow;
public uint NumberOfLinks;
public uint FileIndexHigh;
public uint FileIndexLow;
}
//
// CreateFile constants
//
const uint FILE_SHARE_READ = 0x00000001;
const uint OPEN_EXISTING = 3;
const uint GENERIC_READ = (0x80000000);
const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetFileInformationByHandle(IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);
public static bool IsSameFileAs(this FileSystemInfo file, string path)
{
BY_HANDLE_FILE_INFORMATION fileInfo1, fileInfo2;
IntPtr ptr1 = CreateFile(file.FullName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
if ((int)ptr1 == -1)
{
System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
throw e;
}
IntPtr ptr2 = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
if ((int)ptr2 == -1)
{
System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
throw e;
}
GetFileInformationByHandle(ptr1, out fileInfo1);
GetFileInformationByHandle(ptr2, out fileInfo2);
return ((fileInfo1.FileIndexHigh == fileInfo2.FileIndexHigh) &&
(fileInfo1.FileIndexLow == fileInfo2.FileIndexLow));
}
}