让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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上实现和单元测试。
通过操作系统文件系统信息比较文件/目录。这对于比较共享和本地文件非常有用。
用法:
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));
}
}
一些DataSet/DataRow扩展,使使用db结果更简单
只需在DataRow上使用. field ("fieldname"),如果可以,它将强制转换它,可选的默认值可以包括在内。
还有DataSet上的. hasrows(),这样你就不需要检查表和行的存在。
例子:
using (DataSet ds = yourcall())
{
if (ds.HasRows())
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
int id = dr.Field<int>("ID");
string name = dr.Field<string>("Name");
string Action = dr.Field<string>("Action", "N/A");
}
}
}
代码:
using System;
using System.Data;
public static class DataSetExtensions
{
public static T Field<T>(this DataRow row, string columnName, T defaultValue)
{
try
{
return row.Field<T>(columnName);
}
catch
{
return defaultValue;
}
}
public static T Field<T>(this DataRow row, string columnName)
{
if (row[columnName] == null)
throw new NullReferenceException(columnName + " does not exist in DataRow");
string value = row[columnName].ToString();
if (typeof(T) == "".GetType())
{
return (T)Convert.ChangeType(value, typeof(T));
}
else if (typeof(T) == 0.GetType())
{
return (T)Convert.ChangeType(int.Parse(value), typeof(T));
}
else if (typeof(T) == false.GetType())
{
return (T)Convert.ChangeType(bool.Parse(value), typeof(T));
}
else if (typeof(T) == DateTime.Now.GetType())
{
return (T)Convert.ChangeType(DateTime.Parse(value), typeof(T));
}
else if (typeof(T) == new byte().GetType())
{
return (T)Convert.ChangeType(byte.Parse(value), typeof(T));
}
else if (typeof(T) == new float().GetType())
{
return (T)Convert.ChangeType(float.Parse(value), typeof(T));
}
else
{
throw new ArgumentException(string.Format("Cannot cast '{0}' to '{1}'.", value, typeof(T).ToString()));
}
}
public static bool HasRows(this DataSet dataSet)
{
return (dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0);
}
}
用于winforms填充组合框:
List<MyObject> myObjects = new List<MyObject>() {
new MyObject() {Name = "a", Id = 0},
new MyObject() {Name = "b", Id = 1},
new MyObject() {Name = "c", Id = 2} }
comboBox.FillDataSource<MyObject>(myObjects, x => x.Name);
扩展方法:
/** <summary>Fills the System.Windows.Forms.ComboBox object DataSource with a
* list of T objects.</summary>
* <param name="values">The list of T objects.</param>
* <param name="displayedValue">A function to apply to each element to get the
* display value.</param>
*/
public static void FillDataSource<T>(this ComboBox comboBox, List<T> values,
Func<T, String> displayedValue) {
// Create dataTable
DataTable data = new DataTable();
data.Columns.Add("ValueMember", typeof(T));
data.Columns.Add("DisplayMember");
for (int i = 0; i < values.Count; i++) {
// For each value/displayed value
// Create new row with value & displayed value
DataRow dr = data.NewRow();
dr["ValueMember"] = values[i];
dr["DisplayMember"] = displayedValue(values[i]) ?? "";
// Add row to the dataTable
data.Rows.Add(dr);
}
// Bind datasource to the comboBox
comboBox.DataSource = data;
comboBox.ValueMember = "ValueMember";
comboBox.DisplayMember = "DisplayMember";
}
我相信以前有人这样做过,但我发现自己经常使用这种方法(和更简单的导数):
public static bool CompareEx(this string strA, string strB, CultureInfo culture, bool ignoreCase)
{
return string.Compare(strA, strB, ignoreCase, culture) == 0;
}
您可以以多种方式编写它,但我喜欢它,因为它非常快速地统一了比较字符串的方法,同时节省了代码行数(或代码字符)。