bov*_*ium 478 .net c# extension-methods open-source
让我们列出你发布优秀和最喜欢的扩展方法的答案.
要求是必须发布完整代码并提供示例和如何使用它的说明.
基于对该主题的高度关注,我在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我们需要更多开发人员.;-)
Win*_*ith 232
public static bool In<T>(this T source, params T[] list)
{
if(null==source) throw new ArgumentNullException("source");
return list.Contains(source);
}
Run Code Online (Sandbox Code Playgroud)
允许我替换:
if(reallyLongIntegerVariableName == 1 ||
reallyLongIntegerVariableName == 6 ||
reallyLongIntegerVariableName == 9 ||
reallyLongIntegerVariableName == 11)
{
// do something....
}
and
if(reallyLongStringVariableName == "string1" ||
reallyLongStringVariableName == "string2" ||
reallyLongStringVariableName == "string3")
{
// do something....
}
and
if(reallyLongMethodParameterName == SomeEnum.Value1 ||
reallyLongMethodParameterName == SomeEnum.Value2 ||
reallyLongMethodParameterName == SomeEnum.Value3 ||
reallyLongMethodParameterName == SomeEnum.Value4)
{
// do something....
}
Run Code Online (Sandbox Code Playgroud)
附:
if(reallyLongIntegerVariableName.In(1,6,9,11))
{
// do something....
}
and
if(reallyLongStringVariableName.In("string1","string2","string3"))
{
// do something....
}
and
if(reallyLongMethodParameterName.In(SomeEnum.Value1, SomeEnum.Value2, SomeEnum.Value3, SomeEnum.Value4)
{
// do something....
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 160
我在MiscUtil项目中有各种扩展方法(那里有完整的源代码 - 我不打算在这里重复它).我最喜欢的,其中一些涉及其他类(如范围):
日期和时间 - 主要用于单元测试.不确定我是否会在生产中使用它们:)
var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();
Run Code Online (Sandbox Code Playgroud)
范围和踩踏 - 非常感谢Marc Gravell为他的操作员提供的服务:
var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());
Run Code Online (Sandbox Code Playgroud)
比较:
var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();
Run Code Online (Sandbox Code Playgroud)
参数检查:
x.ThrowIfNull("x");
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
推LINQ - 在这里解释需要很长时间,但要搜索它.
cha*_*rit 147
string.Format快捷方式:
public static class StringExtensions
{
// Enable quick and more natural string.Format calls
public static string F(this string s, params object[] args)
{
return string.Format(s, args);
}
}
Run Code Online (Sandbox Code Playgroud)
例:
var s = "The co-ordinate is ({0}, {1})".F(point.X, point.Y);
Run Code Online (Sandbox Code Playgroud)
要快速复制粘贴,请转到此处.
你不觉得打字更自然吗? "some string".F("param")而不是string.Format("some string", "param")?
更多 易读的名称,请尝试以下建议之一:
s = "Hello {0} world {1}!".Fmt("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatBy("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatWith("Stack", "Overflow");
s = "Hello {0} world {1}!".Display("Stack", "Overflow");
s = "Hello {0} world {1}!".With("Stack", "Overflow");
Run Code Online (Sandbox Code Playgroud)
..
xyz*_*xyz 89
这些有用吗?
public static bool CoinToss(this Random rng)
{
return rng.Next(2) == 0;
}
public static T OneOf<T>(this Random rng, params T[] things)
{
return things[rng.Next(things.Length)];
}
Random rand;
bool luckyDay = rand.CoinToss();
string babyName = rand.OneOf("John", "George", "Radio XBR74 ROCKS!");
Run Code Online (Sandbox Code Playgroud)
CMS*_*CMS 76
public static class ComparableExtensions
{
public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
{
return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
}
}
Run Code Online (Sandbox Code Playgroud)
例:
if (myNumber.Between(3,7))
{
// ....
}
Run Code Online (Sandbox Code Playgroud)
小智 58
扩展方法:
public static void AddRange<T, S>(this ICollection<T> list, params S[] values)
where S : T
{
foreach (S value in values)
list.Add(value);
}
Run Code Online (Sandbox Code Playgroud)
该方法适用于所有类型,并允许您将一系列项目作为参数添加到列表中.
例:
var list = new List<Int32>();
list.AddRange(5, 4, 8, 4, 2);
Run Code Online (Sandbox Code Playgroud)
TWi*_*ars 55
一定要把它放在codeplex项目中.
将对象序列化/反序列化为XML:
/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, obj);
return writer.ToString();
}
}
/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
if (xml == null) throw new ArgumentNullException("xml");
var serializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(xml))
{
try { return (T)serializer.Deserialize(reader); }
catch { return null; } // Could not be deserialized to this type.
}
}
Run Code Online (Sandbox Code Playgroud)
cha*_*rit 46
ForEach for IEnumerables
public static class FrameworkExtensions
{
// a map function
public static void ForEach<T>(this IEnumerable<T> @enum, Action<T> mapFunction)
{
foreach (var item in @enum) mapFunction(item);
}
}
Run Code Online (Sandbox Code Playgroud)
天真的例子:
var buttons = GetListOfButtons() as IEnumerable<Button>;
// click all buttons
buttons.ForEach(b => b.Click());
Run Code Online (Sandbox Code Playgroud)
很酷的例子:
// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
.ForEach(item => {
item.Number = 1;
item.Str = "Hello World!";
});
Run Code Online (Sandbox Code Playgroud)
注意:
这不是Select因为Select 期望你的函数返回一些东西,就像转换到另一个列表一样.
ForEach只允许您为每个项执行某些操作而无需任何转换/数据操作.
我做了这个,所以我可以用更实用的风格编程,我很惊讶List有一个ForEach而IEnumerable没有.
把它放在codeplex项目中
The*_*edi 43
我的转换扩展程序允许您执行以下操作:
int i = myString.To<int>();
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在失败时请求默认值(调用空白构造函数或"0"表示数字),指定"默认"值(我称之为"其他"),或者请求null(其中T:class).我还提供了两个静默异常模型,以及一个返回bool的典型TryParse模型,指示所采取的操作,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>();
Run Code Online (Sandbox Code Playgroud)
我无法让Nullable类型非常干净地滚动到整个事物中.在我扔掉毛巾之前,我试了大约20分钟.
小智 43
我有一个记录异常的扩展方法:
public static void Log(this Exception obj)
{
//your logging logic here
}
Run Code Online (Sandbox Code Playgroud)
它使用如下:
try
{
//Your stuff here
}
catch(Exception ex)
{
ex.Log();
}
Run Code Online (Sandbox Code Playgroud)
[抱歉发布两次; 第二个是更好的设计:-)]
mla*_*sen 38
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);
}
}
Run Code Online (Sandbox Code Playgroud)
用于将字符串解析为枚举.
public enum TestEnum
{
Bar,
Test
}
public class Test
{
public void Test()
{
TestEnum foo = "Test".EnumParse<TestEnum>();
}
}
Run Code Online (Sandbox Code Playgroud)
幸得斯科特·多尔曼
---编辑Codeplex项目---
我问Scott Dorman是否会介意我们在Codeplex项目中发布他的代码.这是我从他那里得到的答复:
感谢SO帖子和CodePlex项目的单挑.我对这个问题提出了答案.是的,该代码实际上属于CodeProject Open License(http://www.codeproject.com/info/cpol10.aspx)下的公共域.
我在CodePlex项目中包含它没有任何问题,如果你想将我添加到项目中(用户名是sdorman),我将添加该方法以及一些额外的枚举助手方法.
Jul*_*iet 32
我发现这个非常有用:
public static class PaulaBean
{
private static String paula = "Brillant";
public static String GetPaula<T>(this T obj) {
return paula;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在CodePlex上使用它.
CMS*_*CMS 31
例子:
DateTime firstDayOfMonth = DateTime.Now.First();
DateTime lastdayOfMonth = DateTime.Now.Last();
DateTime lastFridayInMonth = DateTime.Now.Last(DayOfWeek.Friday);
DateTime nextFriday = DateTime.Now.Next(DayOfWeek.Friday);
DateTime lunchTime = DateTime.Now.SetTime(11, 30);
DateTime noonOnFriday = DateTime.Now.Next(DayOfWeek.Friday).Noon();
DateTime secondMondayOfMonth = DateTime.Now.First(DayOfWeek.Monday).Next(DayOfWeek.Monday).Midnight();
Run Code Online (Sandbox Code Playgroud)
Ven*_*enr 28
这是我经常用于演示文稿格式化的一个.
public static string ToTitleCase(this string mText)
{
if (mText == null) return mText;
System.Globalization.CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Globalization.TextInfo textInfo = cultureInfo.TextInfo;
// TextInfo.ToTitleCase only operates on the string if is all lower case, otherwise it returns the string unchanged.
return textInfo.ToTitleCase(mText.ToLower());
}
Run Code Online (Sandbox Code Playgroud)
Jes*_*cer 28
这是罗马数字的来往.不经常使用,但可能很方便.用法:
if ("IV".IsValidRomanNumeral())
{
// Do useful stuff with the number 4.
}
Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());
Run Code Online (Sandbox Code Playgroud)
来源:
public static class RomanNumeralExtensions
{
private const int NumberOfRomanNumeralMaps = 13;
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "M", 1000 },
{ "CM", 900 },
{ "D", 500 },
{ "CD", 400 },
{ "C", 100 },
{ "XC", 90 },
{ "L", 50 },
{ "XL", 40 },
{ "X", 10 },
{ "IX", 9 },
{ "V", 5 },
{ "IV", 4 },
{ "I", 1 }
};
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
Pao*_*sco 25
处理尺寸的便捷方式:
public static class Extensions {
public static int K(this int value) {
return value * 1024;
}
public static int M(this int value) {
return value * 1024 * 1024;
}
}
public class Program {
public void Main() {
WSHttpContextBinding serviceMultipleTokenBinding = new WSHttpContextBinding() {
MaxBufferPoolSize = 2.M(), // instead of 2097152
MaxReceivedMessageSize = 64.K(), // instead of 65536
};
}
}
Run Code Online (Sandbox Code Playgroud)
fre*_*e0n 24
对于Winform控件:
/// <summary>
/// Returns whether the function is being executed during design time in Visual Studio.
/// </summary>
public static bool IsDesignTime(this Control control)
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return true;
}
if (control.Site != null && control.Site.DesignMode)
{
return true;
}
var parent = control.Parent;
while (parent != null)
{
if (parent.Site != null && parent.Site.DesignMode)
{
return true;
}
parent = parent.Parent;
}
return false;
}
/// <summary>
/// Sets the DropDownWidth to ensure that no item's text is cut off.
/// </summary>
public static void SetDropDownWidth(this ComboBox comboBox)
{
var g = comboBox.CreateGraphics();
var font = comboBox.Font;
float maxWidth = 0;
foreach (var item in comboBox.Items)
{
maxWidth = Math.Max(maxWidth, g.MeasureString(item.ToString(), font).Width);
}
if (comboBox.Items.Count > comboBox.MaxDropDownItems)
{
maxWidth += SystemInformation.VerticalScrollBarWidth;
}
comboBox.DropDownWidth = Math.Max(comboBox.Width, Convert.ToInt32(maxWidth));
}
Run Code Online (Sandbox Code Playgroud)
IsDesignTime用法:
public class SomeForm : Form
{
public SomeForm()
{
InitializeComponent();
if (this.IsDesignTime())
{
return;
}
// Do something that makes the visual studio crash or hang if we're in design time,
// but any other time executes just fine
}
}
Run Code Online (Sandbox Code Playgroud)
SetDropdownWidth用法:
ComboBox cbo = new ComboBox { Width = 50 };
cbo.Items.Add("Short");
cbo.Items.Add("A little longer");
cbo.Items.Add("Holy cow, this is a really, really long item. How in the world will it fit?");
cbo.SetDropDownWidth();
Run Code Online (Sandbox Code Playgroud)
我忘了提及,随意在Codeplex上使用这些...
bov*_*ium 23
ThrowIfArgumentIsNull是一个很好的方法来做我们都应该做的空检查.
public static class Extensions
{
public static void ThrowIfArgumentIsNull<T>(this T obj, string parameterName) where T : class
{
if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
}
}
Run Code Online (Sandbox Code Playgroud)
下面是使用它的方法,它适用于命名空间中的所有类或在其中使用命名空间的任何位置.
internal class Test
{
public Test(string input1)
{
input1.ThrowIfArgumentIsNull("input1");
}
}
Run Code Online (Sandbox Code Playgroud)
可以在CodePlex项目上使用此代码.
cha*_*rit 22
移动到C#时,我想念Visual Basic的With语句,所以这里:
public static void With<T>(this T obj, Action<T> act) { act(obj); }
Run Code Online (Sandbox Code Playgroud)
以下是如何在C#中使用它:
someVeryVeryLonggggVariableName.With(x => {
x.Int = 123;
x.Str = "Hello";
x.Str2 = " World!";
});
Run Code Online (Sandbox Code Playgroud)
节省了很多打字!
比较这个:
someVeryVeryLonggggVariableName.Int = 123;
someVeryVeryLonggggVariableName.Str = "Hello";
someVeryVeryLonggggVariableName.Str2 = " World!";
Run Code Online (Sandbox Code Playgroud)
放入codeplex项目
µBi*_*Bio 18
采用camelCaseWord或PascalCaseWord并将其"字形化",即camelCaseWord => camel Case Word
public static string Wordify( this string camelCaseWord )
{
// if the word is all upper, just return it
if( !Regex.IsMatch( camelCaseWord, "[a-z]" ) )
return camelCaseWord;
return string.Join( " ", Regex.Split( camelCaseWord, @"(?<!^)(?=[A-Z])" ) );
}
Run Code Online (Sandbox Code Playgroud)
我经常将它与Capitalize结合使用
public static string Capitalize( this string word )
{
return word[0].ToString( ).ToUpper( ) + word.Substring( 1 );
}
Run Code Online (Sandbox Code Playgroud)
用法示例
SomeEntityObject entity = DataAccessObject.GetSomeEntityObject( id );
List<PropertyInfo> properties = entity.GetType().GetPublicNonCollectionProperties( );
// wordify the property names to act as column headers for an html table or something
List<string> columns = properties.Select( p => p.Name.Capitalize( ).Wordify( ) ).ToList( );
Run Code Online (Sandbox Code Playgroud)
免费在codeplex项目中使用
Vas*_*nan 17
我发现这个有用
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
return pSeq ?? Enumerable.Empty<T>();
}
Run Code Online (Sandbox Code Playgroud)
它删除了调用代码中的空检查.你现在可以做
MyList.EmptyIfNull().Where(....)
Run Code Online (Sandbox Code Playgroud)
CMS*_*CMS 16
将double转换为使用指定区域性格式化的字符串:
public static class ExtensionMethods
{
public static string ToCurrency(this double value, string cultureName)
{
CultureInfo currentCulture = new CultureInfo(cultureName);
return (string.Format(currentCulture, "{0:C}", value));
}
}
Run Code Online (Sandbox Code Playgroud)
例:
double test = 154.20;
string testString = test.ToCurrency("en-US"); // $154.20
Run Code Online (Sandbox Code Playgroud)
Chr*_*s S 15
下面是一个扩展方法,它适应Rick Strahl的代码(以及注释),以阻止您每次将其转换为字符串时猜测或读取字节数组或文本文件的字节顺序标记.
该片段允许您简单地执行:
byte[] buffer = File.ReadAllBytes(@"C:\file.txt");
string content = buffer.GetString();
Run Code Online (Sandbox Code Playgroud)
如果您发现任何错误,请添加评论.随意将其包含在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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
sco*_*obi 15
这是我今天刚刚创建的.
// requires .NET 4
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue = default(TReturn)) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
// versions for CLR 2, which doesn't support optional params
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func)
where TIn : class
{ return obj != null ? func(obj) : default(TReturn); }
Run Code Online (Sandbox Code Playgroud)
它可以让你这样做:
var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());
Run Code Online (Sandbox Code Playgroud)
哪个更流畅,(IMO)更容易阅读比这个:
var lname = (thingy != null ? thingy.Name : null) != null
? thingy.Name.ToLower() : null;
Run Code Online (Sandbox Code Playgroud)
Ada*_*sek 14
在从MySqlDataReader中提取值时,我厌倦了繁琐的空值检查,因此:
public static DateTime? GetNullableDateTime(this MySqlDataReader dr, string fieldName)
{
DateTime? nullDate = null;
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullDate : dr.GetDateTime(fieldName);
}
public static string GetNullableString(this MySqlDataReader dr, string fieldName)
{
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? String.Empty : dr.GetString(fieldName);
}
public static char? GetNullableChar(this MySqlDataReader dr, string fieldName)
{
char? nullChar = null;
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullChar : dr.GetChar(fieldName);
}
Run Code Online (Sandbox Code Playgroud)
当然,这可以与任何SqlDataReader一起使用.
好事和Joe对如何做到这一点都有一些很好的评论,之后我有机会在不同的上下文中实现类似的东西,所以这是另一个版本:
public static int? GetNullableInt32(this IDataRecord dr, int ordinal)
{
int? nullInt = null;
return dr.IsDBNull(ordinal) ? nullInt : dr.GetInt32(ordinal);
}
public static int? GetNullableInt32(this IDataRecord dr, string fieldname)
{
int ordinal = dr.GetOrdinal(fieldname);
return dr.GetNullableInt32(ordinal);
}
public static bool? GetNullableBoolean(this IDataRecord dr, int ordinal)
{
bool? nullBool = null;
return dr.IsDBNull(ordinal) ? nullBool : dr.GetBoolean(ordinal);
}
public static bool? GetNullableBoolean(this IDataRecord dr, string fieldname)
{
int ordinal = dr.GetOrdinal(fieldname);
return dr.GetNullableBoolean(ordinal);
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*tum 14
"请在接受将代码放入Codeplex项目时标记您的答案."
为什么?这个网站上的所有东西都在CC-by-sa-2.5下,所以只需将你的扩展溢出项目置于相同的许可下,你就可以自由使用它了.
无论如何,这是一个String.Reverse函数,基于这个问题.
/// <summary>
/// Reverse a String
/// </summary>
/// <param name="input">The string to Reverse</param>
/// <returns>The reversed String</returns>
public static string Reverse(this string input)
{
char[] array = input.ToCharArray();
Array.Reverse(array);
return new string(array);
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*ler 14
令我恼火的是,LINQ给了我一个OrderBy,它接受一个实现IComparer作为参数的类,但不支持传入一个简单的匿名比较器函数.我纠正了这一点.
这个类从比较器函数创建一个IComparer ...
/// <summary>
/// Creates an <see cref="IComparer{T}"/> instance for the given
/// delegate function.
/// </summary>
internal class ComparerFactory<T> : IComparer<T>
{
public static IComparer<T> Create(Func<T, T, int> comparison)
{
return new ComparerFactory<T>(comparison);
}
private readonly Func<T, T, int> _comparison;
private ComparerFactory(Func<T, T, int> comparison)
{
_comparison = comparison;
}
#region IComparer<T> Members
public int Compare(T x, T y)
{
return _comparison(x, y);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
...并且这些扩展方法在枚举上公开了我的新OrderBy重载.我怀疑它适用于LINQ to SQL,但它对于LINQ to Objects非常有用.
public static class EnumerableExtensions
{
/// <summary>
/// Sorts the elements of a sequence in ascending order by using a specified comparison delegate.
/// </summary>
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TKey, TKey, int> comparison)
{
var comparer = ComparerFactory<TKey>.Create(comparison);
return source.OrderBy(keySelector, comparer);
}
/// <summary>
/// Sorts the elements of a sequence in descending order by using a specified comparison delegate.
/// </summary>
public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TKey, TKey, int> comparison)
{
var comparer = ComparerFactory<TKey>.Create(comparison);
return source.OrderByDescending(keySelector, comparer);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你愿意,欢迎你把它放在codeplex上.
Eri*_*ver 13
这个适用于MVC,它增加了为每个可用<label />的Html变量生成标记的功能ViewPage.希望它对试图开发类似扩展的其他人有用.
使用:
<%= Html.Label("LabelId", "ForId", "Text")%>
Run Code Online (Sandbox Code Playgroud)
输出:
<label id="LabelId" for="ForId">Text</label>
Run Code Online (Sandbox Code Playgroud)
码:
public static class HtmlHelperExtensions
{
public static string Label(this HtmlHelper Html, string @for, string text)
{
return Html.Label(null, @for, text);
}
public static string Label(this HtmlHelper Html, string @for, string text, object htmlAttributes)
{
return Html.Label(null, @for, text, htmlAttributes);
}
public static string Label(this HtmlHelper Html, string @for, string text, IDictionary<string, object> htmlAttributes)
{
return Html.Label(null, @for, text, htmlAttributes);
}
public static string Label(this HtmlHelper Html, string id, string @for, string text)
{
return Html.Label(id, @for, text, null);
}
public static string Label(this HtmlHelper Html, string id, string @for, string text, object htmlAttributes)
{
return Html.Label(id, @for, text, new RouteValueDictionary(htmlAttributes));
}
public static string Label(this HtmlHelper Html, string id, string @for, string text, IDictionary<string, object> htmlAttributes)
{
TagBuilder tag = new TagBuilder("label");
tag.MergeAttributes(htmlAttributes);
if (!string.IsNullOrEmpty(id))
tag.MergeAttribute("id", Html.AttributeEncode(id));
tag.MergeAttribute("for", Html.AttributeEncode(@for));
tag.SetInnerText(Html.Encode(text));
return tag.ToString(TagRenderMode.Normal);
}
}
Run Code Online (Sandbox Code Playgroud)
Max*_*oro 12
转过来:
DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT @param";
DbParameter param = command.CreateParameter();
param.ParameterName = "@param";
param.Value = "Hello World";
command.Parameters.Add(param);
Run Code Online (Sandbox Code Playgroud)
......进入这个:
DbCommand command = connection.CreateCommand("SELECT {0}", "Hello World");
Run Code Online (Sandbox Code Playgroud)
...使用此扩展方法:
using System;
using System.Data.Common;
using System.Globalization;
using System.Reflection;
namespace DbExtensions {
public static class Db {
static readonly Func<DbConnection, DbProviderFactory> getDbProviderFactory;
static readonly Func<DbCommandBuilder, int, string> getParameterName;
static readonly Func<DbCommandBuilder, int, string> getParameterPlaceholder;
static Db() {
getDbProviderFactory = (Func<DbConnection, DbProviderFactory>)Delegate.CreateDelegate(typeof(Func<DbConnection, DbProviderFactory>), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
getParameterName = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
getParameterPlaceholder = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterPlaceholder", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
}
public static DbProviderFactory GetProviderFactory(this DbConnection connection) {
return getDbProviderFactory(connection);
}
public static DbCommand CreateCommand(this DbConnection connection, string commandText, params object[] parameters) {
if (connection == null) throw new ArgumentNullException("connection");
return CreateCommandImpl(GetProviderFactory(connection).CreateCommandBuilder(), connection.CreateCommand(), commandText, parameters);
}
private static DbCommand CreateCommandImpl(DbCommandBuilder commandBuilder, DbCommand command, string commandText, params object[] parameters) {
if (commandBuilder == null) throw new ArgumentNullException("commandBuilder");
if (command == null) throw new ArgumentNullException("command");
if (commandText == null) throw new ArgumentNullException("commandText");
if (parameters == null || parameters.Length == 0) {
command.CommandText = commandText;
return command;
}
object[] paramPlaceholders = new object[parameters.Length];
for (int i = 0; i < paramPlaceholders.Length; i++) {
DbParameter dbParam = command.CreateParameter();
dbParam.ParameterName = getParameterName(commandBuilder, i);
dbParam.Value = parameters[i] ?? DBNull.Value;
command.Parameters.Add(dbParam);
paramPlaceholders[i] = getParameterPlaceholder(commandBuilder, i);
}
command.CommandText = String.Format(CultureInfo.InvariantCulture, commandText, paramPlaceholders);
return command;
}
}
}
Run Code Online (Sandbox Code Playgroud)
更多ADO.NET扩展方法:DbExtensions
mat*_*mc3 11
我最喜欢的一个是String上的IsLike()扩展.IsLike()匹配VB的Like运算符,当你不想编写一个完整的正则表达式来解决你的问题时,它很方便.用法是这样的:
"abc".IsLike("a*"); // true
"Abc".IsLike("[A-Z][a-z][a-z]"); // true
"abc123".IsLike("*###"); // true
"hat".IsLike("?at"); // true
"joe".IsLike("[!aeiou]*"); // true
"joe".IsLike("?at"); // false
"joe".IsLike("[A-Z][a-z][a-z]"); // false
Run Code Online (Sandbox Code Playgroud)
这是代码
public static class StringEntentions {
/// <summary>
/// Indicates whether the current string matches the supplied wildcard pattern. Behaves the same
/// as VB's "Like" Operator.
/// </summary>
/// <param name="s">The string instance where the extension method is called</param>
/// <param name="wildcardPattern">The wildcard pattern to match. Syntax matches VB's Like operator.</param>
/// <returns>true if the string matches the supplied pattern, false otherwise.</returns>
/// <remarks>See http://msdn.microsoft.com/en-us/library/swf8kaxw(v=VS.100).aspx</remarks>
public static bool IsLike(this string s, string wildcardPattern) {
if (s == null || String.IsNullOrEmpty(wildcardPattern)) return false;
// turn into regex pattern, and match the whole string with ^$
var regexPattern = "^" + Regex.Escape(wildcardPattern) + "$";
// add support for ?, #, *, [], and [!]
regexPattern = regexPattern.Replace(@"\[!", "[^")
.Replace(@"\[", "[")
.Replace(@"\]", "]")
.Replace(@"\?", ".")
.Replace(@"\*", ".*")
.Replace(@"\#", @"\d");
var result = false;
try {
result = Regex.IsMatch(s, regexPattern);
}
catch (ArgumentException ex) {
throw new ArgumentException(String.Format("Invalid pattern: {0}", wildcardPattern), ex);
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
joh*_*hnc 10
类似于上面的字符串As和Is,但是对所有对象都是全局的.
这很简单,但是我用这些来减轻拳击的parens爆炸.
public static class ExtensionMethods_Object
{
[DebuggerStepThrough()]
public static bool Is<T>(this object item) where T : class
{
return item is T;
}
[DebuggerStepThrough()]
public static bool IsNot<T>(this object item) where T : class
{
return !(item.Is<T>());
}
[DebuggerStepThrough()]
public static T As<T>(this object item) where T : class
{
return item as T;
}
}
Run Code Online (Sandbox Code Playgroud)
我很高兴这个代码在codeplex中使用,实际上它已经是.
对我来说另一个有用的:
/// <summary>
/// Converts any type in to an Int32
/// </summary>
/// <typeparam name="T">Any Object</typeparam>
/// <param name="value">Value to convert</param>
/// <returns>The integer, 0 if unsuccessful</returns>
public static int ToInt32<T>(this T value)
{
int result;
if (int.TryParse(value.ToString(), out result))
{
return result;
}
return 0;
}
/// <summary>
/// Converts any type in to an Int32 but if null then returns the default
/// </summary>
/// <param name="value">Value to convert</param>
/// <typeparam name="T">Any Object</typeparam>
/// <param name="defaultValue">Default to use</param>
/// <returns>The defaultValue if unsuccessful</returns>
public static int ToInt32<T>(this T value, int defaultValue)
{
int result;
if (int.TryParse(value.ToString(), out result))
{
return result;
}
return defaultValue;
}
Run Code Online (Sandbox Code Playgroud)
例:
int number = "123".ToInt32();
Run Code Online (Sandbox Code Playgroud)
要么:
int badNumber = "a".ToInt32(100); // Returns 100 since a is nan
Run Code Online (Sandbox Code Playgroud)
IEnumerable<> 拖曳我用Fisher-Yates算法实现了一个shuffle函数.
通过yield return在两个函数中使用和破坏代码,它实现了正确的参数验证和延迟执行.(谢谢Dan,我在第一个版本中指出了这个缺陷)
static public IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
if (source == null) throw new ArgumentNullException("source");
return ShuffleIterator(source);
}
static private IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source)
{
T[] array = source.ToArray();
Random rnd = new Random();
for (int n = array.Length; n > 1;)
{
int k = rnd.Next(n--); // 0 <= k < n
//Swap items
if (n != k)
{
T tmp = array[k];
array[k] = array[n];
array[n] = tmp;
}
}
foreach (var item in array) yield return item;
}
Run Code Online (Sandbox Code Playgroud)
你可以从Random课堂上获得很多功能.
以下是我不时使用的一些扩展方法.有了这些,除了Next与NextDouble中,Random类为您NextBool,NextChar,NextDateTime,NextTimeSpan,NextDouble(接受minValue和maxValue参数),以及我个人最喜欢的:NextString.有多种(NextByte,NextShort,NextLong等); 但这些主要是为了完整性,并没有得到那么多的使用.所以我没有在这里包含它们(这段代码足够长,因为它!).
// todo: implement additional CharType values (e.g., AsciiAny)
public enum CharType {
AlphabeticLower,
AlphabeticUpper,
AlphabeticAny,
AlphanumericLower,
AlphanumericUpper,
AlphanumericAny,
Numeric
}
public static class RandomExtensions {
// 10 digits vs. 52 alphabetic characters (upper & lower);
// probability of being numeric: 10 / 62 = 0.1612903225806452
private const double AlphanumericProbabilityNumericAny = 10.0 / 62.0;
// 10 digits vs. 26 alphabetic characters (upper OR lower);
// probability of being numeric: 10 / 36 = 0.2777777777777778
private const double AlphanumericProbabilityNumericCased = 10.0 / 36.0;
public static bool NextBool(this Random random, double probability) {
return random.NextDouble() <= probability;
}
public static bool NextBool(this Random random) {
return random.NextDouble() <= 0.5;
}
public static char NextChar(this Random random, CharType mode) {
switch (mode) {
case CharType.AlphabeticAny:
return random.NextAlphabeticChar();
case CharType.AlphabeticLower:
return random.NextAlphabeticChar(false);
case CharType.AlphabeticUpper:
return random.NextAlphabeticChar(true);
case CharType.AlphanumericAny:
return random.NextAlphanumericChar();
case CharType.AlphanumericLower:
return random.NextAlphanumericChar(false);
case CharType.AlphanumericUpper:
return random.NextAlphanumericChar(true);
case CharType.Numeric:
return random.NextNumericChar();
default:
return random.NextAlphanumericChar();
}
}
public static char NextChar(this Random random) {
return random.NextChar(CharType.AlphanumericAny);
}
private static char NextAlphanumericChar(this Random random, bool uppercase) {
bool numeric = random.NextBool(AlphanumericProbabilityNumericCased);
if (numeric)
return random.NextNumericChar();
else
return random.NextAlphabeticChar(uppercase);
}
private static char NextAlphanumericChar(this Random random) {
bool numeric = random.NextBool(AlphanumericProbabilityNumericAny);
if (numeric)
return random.NextNumericChar();
else
return random.NextAlphabeticChar(random.NextBool());
}
private static char NextAlphabeticChar(this Random random, bool uppercase) {
if (uppercase)
return (char)random.Next(65, 91);
else
return (char)random.Next(97, 123);
}
private static char NextAlphabeticChar(this Random random) {
return random.NextAlphabeticChar(random.NextBool());
}
private static char NextNumericChar(this Random random) {
return (char)random.Next(48, 58);
}
public static DateTime NextDateTime(this Random random, DateTime minValue, DateTime maxValue) {
return DateTime.FromOADate(
random.NextDouble(minValue.ToOADate(), maxValue.ToOADate())
);
}
public static DateTime NextDateTime(this Random random) {
return random.NextDateTime(DateTime.MinValue, DateTime.MaxValue);
}
public static double NextDouble(this Random random, double minValue, double maxValue) {
if (maxValue < minValue)
throw new ArgumentException("Minimum value must be less than maximum value.");
double difference = maxValue - minValue;
if (!double.IsInfinity(difference))
return minValue + (random.NextDouble() * difference);
else {
// to avoid evaluating to Double.Infinity, we split the range into two halves:
double halfDifference = (maxValue * 0.5) - (minValue * 0.5);
// 50/50 chance of returning a value from the first or second half of the range
if (random.NextBool())
return minValue + (random.NextDouble() * halfDifference);
else
return (minValue + halfDifference) + (random.NextDouble() * halfDifference);
}
}
public static string NextString(this Random random, int numChars, CharType mode) {
char[] chars = new char[numChars];
for (int i = 0; i < numChars; ++i)
chars[i] = random.NextChar(mode);
return new string(chars);
}
public static string NextString(this Random random, int numChars) {
return random.NextString(numChars, CharType.AlphanumericAny);
}
public static TimeSpan NextTimeSpan(this Random random, TimeSpan minValue, TimeSpan maxValue) {
return TimeSpan.FromMilliseconds(
random.NextDouble(minValue.TotalMilliseconds, maxValue.TotalMilliseconds)
);
}
public static TimeSpan NextTimeSpan(this Random random) {
return random.NextTimeSpan(TimeSpan.MinValue, TimeSpan.MaxValue);
}
}
Run Code Online (Sandbox Code Playgroud)
我很失望.NET Framework更喜欢将文件和目录表示为字符串而不是对象,并且FileInfo和DirectoryInfo类型不像我希望的那样强大.所以,我开始编写流畅的扩展方法,因为我需要它们,例如:
public static FileInfo SetExtension(this FileInfo fileInfo, string extension)
{
return new FileInfo(Path.ChangeExtension(fileInfo.FullName, extension));
}
public static FileInfo SetDirectory(this FileInfo fileInfo, string directory)
{
return new FileInfo(Path.Combine(directory, fileInfo.Name));
}
Run Code Online (Sandbox Code Playgroud)
是的,你可以把它放在codeplex中
小智 8
一些我最好的方法扩展(我有很多!):
public static T ToEnum<T>(this string str) where T : struct
{
return (T)Enum.Parse(typeof(T), str);
}
//DayOfWeek sunday = "Sunday".ToEnum<DayOfWeek>();
public static string ToString<T>(this IEnumerable<T> collection, string separator)
{
return ToString(collection, t => t.ToString(), separator);
}
public static string ToString<T>(this IEnumerable<T> collection, Func<T, string> stringElement, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (var item in collection)
{
sb.Append(stringElement(item));
sb.Append(separator);
}
return sb.ToString(0, Math.Max(0, sb.Length - separator.Length)); // quita el ultimo separador
}
//new []{1,2,3}.ToString(i=>i*2, ", ") --> "2, 4, 6"
Run Code Online (Sandbox Code Playgroud)
此外,接下来的几乎意味着能够在几乎任何情况下继续在同一行,而不是声明新的变量,然后删除状态:
public static R Map<T, R>(this T t, Func<T, R> func)
{
return func(t);
}
ExpensiveFindWally().Map(wally=>wally.FirstName + " " + wally.LastName)
public static R TryCC<T, R>(this T t, Func<T, R> func)
where T : class
where R : class
{
if (t == null) return null;
return func(t);
}
public static R? TryCS<T, R>(this T t, Func<T, R> func)
where T : class
where R : struct
{
if (t == null) return null;
return func(t);
}
public static R? TryCS<T, R>(this T t, Func<T, R?> func)
where T : class
where R : struct
{
if (t == null) return null;
return func(t);
}
public static R TrySC<T, R>(this T? t, Func<T, R> func)
where T : struct
where R : class
{
if (t == null) return null;
return func(t.Value);
}
public static R? TrySS<T, R>(this T? t, Func<T, R> func)
where T : struct
where R : struct
{
if (t == null) return null;
return func(t.Value);
}
public static R? TrySS<T, R>(this T? t, Func<T, R?> func)
where T : struct
where R : struct
{
if (t == null) return null;
return func(t.Value);
}
//int? bossNameLength = Departament.Boss.TryCC(b=>b.Name).TryCS(s=>s.Length);
public static T ThrowIfNullS<T>(this T? t, string mensaje)
where T : struct
{
if (t == null)
throw new NullReferenceException(mensaje);
return t.Value;
}
public static T ThrowIfNullC<T>(this T t, string mensaje)
where T : class
{
if (t == null)
throw new NullReferenceException(mensaje);
return t;
}
public static T Do<T>(this T t, Action<T> action)
{
action(t);
return t;
}
//Button b = new Button{Content = "Click"}.Do(b=>Canvas.SetColumn(b,2));
public static T TryDo<T>(this T t, Action<T> action) where T : class
{
if (t != null)
action(t);
return t;
}
public static T? TryDoS<T>(this T? t, Action<T> action) where T : struct
{
if (t != null)
action(t.Value);
return t;
}
Run Code Online (Sandbox Code Playgroud)
希望它看起来不像来自火星:)
与Timespan相关的扩展,例如:
public static TimeSpan Seconds(this int seconds)
{
return TimeSpan.FromSeconds(seconds);
}
public static TimeSpan Minutes(this int minutes)
{
return TimeSpan.FromMinutes(minutes);
}
Run Code Online (Sandbox Code Playgroud)
允许使用:
1.Seconds()
20.Minutes()
Run Code Online (Sandbox Code Playgroud)
锁定扩展名如:
public static IDisposable GetReadLock(this ReaderWriterLockSlim slimLock)
{
slimLock.EnterReadLock();
return new DisposableAction(slimLock.ExitReadLock);
}
public static IDisposable GetWriteLock(this ReaderWriterLockSlim slimLock)
{
slimLock.EnterWriteLock();
return new DisposableAction(slimLock.ExitWriteLock);
}
public static IDisposable GetUpgradeableReadLock(this ReaderWriterLockSlim slimLock)
{
slimLock.EnterUpgradeableReadLock();
return new DisposableAction(slimLock.ExitUpgradeableReadLock);
}
Run Code Online (Sandbox Code Playgroud)
允许使用锁定:
using (lock.GetUpgradeableReadLock())
{
// try read
using (lock.GetWriteLock())
{
//do write
}
}
Run Code Online (Sandbox Code Playgroud)
以及Lokad共享图书馆的其他许多内容
我在Silverlight项目中使用这些:
public static void Show(this UIElement element)
{
element.Visibility = Visibility.Visible;
}
public static void Hide(this UIElement element)
{
element.Visibility = Visibility.Collapsed;
}
Run Code Online (Sandbox Code Playgroud)
HTH.这些是我的一些主要内容.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace Insert.Your.Namespace.Here.Helpers
{
public static class Extensions
{
public static bool IsNullOrEmpty<T>(this IEnumerable<T> iEnumerable)
{
// Cheers to Joel Mueller for the bugfix. Was .Count(), now it's .Any()
return iEnumerable == null ||
!iEnumerable.Any();
}
public static IList<T> ToListIfNotNullOrEmpty<T>(this IList<T> iList)
{
return iList.IsNullOrEmpty() ? null : iList;
}
public static PagedList<T> ToPagedListIfNotNullOrEmpty<T>(this PagedList<T> pagedList)
{
return pagedList.IsNullOrEmpty() ? null : pagedList;
}
public static string ToPluralString(this int value)
{
return value == 1 ? string.Empty : "s";
}
public static string ToReadableTime(this DateTime value)
{
TimeSpan span = DateTime.Now.Subtract(value);
const string plural = "s";
if (span.Days > 7)
{
return value.ToShortDateString();
}
switch (span.Days)
{
case 0:
switch (span.Hours)
{
case 0:
if (span.Minutes == 0)
{
return span.Seconds <= 0
? "now"
: string.Format("{0} second{1} ago",
span.Seconds,
span.Seconds != 1 ? plural : string.Empty);
}
return string.Format("{0} minute{1} ago",
span.Minutes,
span.Minutes != 1 ? plural : string.Empty);
default:
return string.Format("{0} hour{1} ago",
span.Hours,
span.Hours != 1 ? plural : string.Empty);
}
default:
return string.Format("{0} day{1} ago",
span.Days,
span.Days != 1 ? plural : string.Empty);
}
}
public static string ToShortGuidString(this Guid value)
{
return Convert.ToBase64String(value.ToByteArray())
.Replace("/", "_")
.Replace("+", "-")
.Substring(0, 22);
}
public static Guid FromShortGuidString(this string value)
{
return new Guid(Convert.FromBase64String(value.Replace("_", "/")
.Replace("-", "+") + "=="));
}
public static string ToStringMaximumLength(this string value, int maximumLength)
{
return ToStringMaximumLength(value, maximumLength, "...");
}
public static string ToStringMaximumLength(this string value, int maximumLength, string postFixText)
{
if (string.IsNullOrEmpty(postFixText))
{
throw new ArgumentNullException("postFixText");
}
return value.Length > maximumLength
? string.Format(CultureInfo.InvariantCulture,
"{0}{1}",
value.Substring(0, maximumLength - postFixText.Length),
postFixText)
:
value;
}
public static string SlugDecode(this string value)
{
return value.Replace("_", " ");
}
public static string SlugEncode(this string value)
{
return value.Replace(" ", "_");
}
}
}
Run Code Online (Sandbox Code Playgroud)
public static class EnumerableExtensions
{
[Pure]
public static U MapReduce<T, U>(this IEnumerable<T> enumerable, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(enumerable != null);
CodeContract.RequiresAlways(enumerable.Skip(1).Any());
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
return enumerable.AsParallel().Select(map).Aggregate(reduce);
}
[Pure]
public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(list != null);
CodeContract.RequiresAlways(list.Count >= 2);
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
U result = map(list[0]);
for (int i = 1; i < list.Count; i++)
{
result = reduce(result,map(list[i]));
}
return result;
}
//Parallel version; creates garbage
[Pure]
public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(list != null);
CodeContract.RequiresAlways(list.Skip(1).Any());
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
U[] mapped = new U[list.Count];
Parallel.For(0, mapped.Length, i =>
{
mapped[i] = map(list[i]);
});
U result = mapped[0];
for (int i = 1; i < list.Count; i++)
{
result = reduce(result, mapped[i]);
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
有时,使用自定义分隔符在列表中的选定元素上写出字符串非常方便.
例如,如果你有一个List<Person>并想要用逗号分隔出姓氏,你可以这样做.
string result = string.Empty;
foreach (var person in personList) {
result += person.LastName + ", ";
}
result = result.Substring(0, result.Length - 2);
return result;
Run Code Online (Sandbox Code Playgroud)
或者你可以使用这个方便的扩展方法
public static string Join<T>(this IEnumerable<T> collection, Func<T, string> func, string separator)
{
return String.Join(separator, collection.Select(func).ToArray());
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它
personList.Join(x => x.LastName, ", ");
Run Code Online (Sandbox Code Playgroud)
它产生相同的结果,在这种情况下是由逗号分隔的姓氏列表.
二进制搜索:
public static T BinarySearch<T, TKey>(this IList<T> list, Func<T, TKey> keySelector, TKey key)
where TKey : IComparable<TKey>
{
int min = 0;
int max = list.Count;
int index = 0;
while (min < max)
{
int mid = (max + min) / 2;
T midItem = list[mid];
TKey midKey = keySelector(midItem);
int comp = midKey.CompareTo(key);
if (comp < 0)
{
min = mid + 1;
}
else if (comp > 0)
{
max = mid - 1;
}
else
{
return midItem;
}
}
if (min == max &&
keySelector(list[min]).CompareTo(key) == 0)
{
return list[min];
}
throw new InvalidOperationException("Item not found");
}
Run Code Online (Sandbox Code Playgroud)
用法(假设列表按Id排序):
var item = list.BinarySearch(i => i.Id, 42);
Run Code Online (Sandbox Code Playgroud)
抛出InvalidOperationException这一事实可能看起来很奇怪,但这就是Enumerable.First在没有匹配项时所做的事情.
到目前为止,我刚刚浏览了所有这4页,我感到非常惊讶,因为我没有看到这种缩短支票的方法InvokeRequired:
using System;
using System.Windows.Forms;
/// <summary>
/// Extension methods acting on Control objects.
/// </summary>
internal static class ControlExtensionMethods
{
/// <summary>
/// Invokes the given action on the given control's UI thread, if invocation is needed.
/// </summary>
/// <param name="control">Control on whose UI thread to possibly invoke.</param>
/// <param name="action">Action to be invoked on the given control.</param>
public static void MaybeInvoke(this Control control, Action action)
{
if (control != null && control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
/// <summary>
/// Maybe Invoke a Func that returns a value.
/// </summary>
/// <typeparam name="T">Return type of func.</typeparam>
/// <param name="control">Control on which to maybe invoke.</param>
/// <param name="func">Function returning a value, to invoke.</param>
/// <returns>The result of the call to func.</returns>
public static T MaybeInvoke<T>(this Control control, Func<T> func)
{
if (control != null && control.InvokeRequired)
{
return (T)(control.Invoke(func));
}
else
{
return func();
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
myForm.MaybeInvoke(() => this.Text = "Hello world");
// Sometimes the control might be null, but that's okay.
var dialogResult = this.Parent.MaybeInvoke(() => MessageBox.Show(this, "Yes or no?", "Choice", MessageBoxButtons.YesNo));
Run Code Online (Sandbox Code Playgroud)
一些日期功能:
public static bool IsFuture(this DateTime date, DateTime from)
{
return date.Date > from.Date;
}
public static bool IsFuture(this DateTime date)
{
return date.IsFuture(DateTime.Now);
}
public static bool IsPast(this DateTime date, DateTime from)
{
return date.Date < from.Date;
}
public static bool IsPast(this DateTime date)
{
return date.IsPast(DateTime.Now);
}
Run Code Online (Sandbox Code Playgroud)
通过OS文件系统信息比较文件/目录的功能.这对于比较共享本地文件很有用.
用法:
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"));
Run Code Online (Sandbox Code Playgroud)
码:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
词典的Pythonic方法:
/// <summary>
/// If a key exists in a dictionary, return its value,
/// otherwise return the default value for that type.
/// </summary>
public static U GetWithDefault<T, U>(this Dictionary<T, U> dict, T key)
{
return dict.GetWithDefault(key, default(U));
}
/// <summary>
/// If a key exists in a dictionary, return its value,
/// otherwise return the provided default value.
/// </summary>
public static U GetWithDefault<T, U>(this Dictionary<T, U> dict, T key, U defaultValue)
{
return dict.ContainsKey(key)
? dict[key]
: defaultValue;
}
Run Code Online (Sandbox Code Playgroud)
当您想要将时间戳附加到文件名以确保唯一性时很有用.
/// <summary>
/// Format a DateTime as a string that contains no characters
//// that are banned from filenames, such as ':'.
/// </summary>
/// <returns>YYYY-MM-DD_HH.MM.SS</returns>
public static string ToFilenameString(this DateTime dt)
{
return dt.ToString("s").Replace(":", ".").Replace('T', '_');
}
Run Code Online (Sandbox Code Playgroud)
小智 6
我通常使用这种扩展方法使用匿名类型来获取字典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;
}
Run Code Online (Sandbox Code Playgroud)
你可以使用它
var dummy = new { color = "#000000", width = "100%", id = "myid" };
Dictionary<string, object> dict = dummy.ToDictionary();
Run Code Online (Sandbox Code Playgroud)
并采用扩展方法
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
}
}
Run Code Online (Sandbox Code Playgroud)
你能行的
dummy.ToDictionary().ForEach((p) => Console.Write("{0}='{1}' ", p.Key, p.Value));
Run Code Online (Sandbox Code Playgroud)
产量
color ='#000000'width ='100%'id ='myid'
我发现自己一遍又一遍地这样做......
public static bool EqualsIgnoreCase(this string a, string b)
{
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
Run Code Online (Sandbox Code Playgroud)
......接着StartsWithIgnoreCase,EndsWithIgnoreCase和ContainsIgnoreCase.
使用密钥为字符串的字典时,使用不区分大小写的搜索返回现有密钥.我们的用例是文件路径.
/// <summary>
/// Gets the key using <paramref name="caseInsensitiveKey"/> from <paramref name="dictionary"/>.
/// </summary>
/// <typeparam name="T">The dictionary value.</typeparam>
/// <param name="dictionary">The dictionary.</param>
/// <param name="caseInsensitiveKey">The case insensitive key.</param>
/// <returns>
/// An existing key; or <see cref="string.Empty"/> if not found.
/// </returns>
public static string GetKeyIgnoringCase<T>(this IDictionary<string, T> dictionary, string caseInsensitiveKey)
{
if (string.IsNullOrEmpty(caseInsensitiveKey)) return string.Empty;
foreach (string key in dictionary.Keys)
{
if (key.Equals(caseInsensitiveKey, StringComparison.InvariantCultureIgnoreCase))
{
return key;
}
}
return string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
static string Format( this string str,
, params Expression<Func<string,object>>[] args)
{
var parameters = args.ToDictionary
( e=>string.Format("{{{0}}}",e.Parameters[0].Name)
, e=>e.Compile()(e.Parameters[0].Name));
var sb = new StringBuilder(str);
foreach(var kv in parameters)
{
sb.Replace( kv.Key
, kv.Value != null ? kv.Value.ToString() : "");
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
使用上面的扩展名你可以这样写:
var str = "{foo} {bar} {baz}".Format(foo=>foo, bar=>2, baz=>new object());
Run Code Online (Sandbox Code Playgroud)
你会得到"foo 2 System.Object".
简单但比"Enumerable.Range"更好,恕我直言:
/// <summary>
/// Replace "Enumerable.Range(n)" with "n.Range()":
/// </summary>
/// <param name="n">iterations</param>
/// <returns>0..n-1</returns>
public static IEnumerable<int> Range(this int n)
{
for (int i = 0; i < n; i++)
yield return i;
}
Run Code Online (Sandbox Code Playgroud)
您可能已经知道扩展方法的一个有趣用法是作为一种混合.一些扩展方法,如XmlSerializable,几乎每个类都污染; 它对大多数人来说没有意义,比如Thread和SqlConnection.
应该将某些功能明确地混合到想要拥有它的类中.我提出了这种类型的新表示法,带有M前缀.
的XmlSerializable话,是这样的:
public interface MXmlSerializable { }
public static class XmlSerializable {
public static string ToXml(this MXmlSerializable self) {
if (self == null) throw new ArgumentNullException();
var serializer = new XmlSerializer(self.GetType());
using (var writer = new StringWriter()) {
serializer.Serialize(writer, self);
return writer.GetStringBuilder().ToString();
}
}
public static T FromXml<T>(string xml) where T : MXmlSerializable {
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(xml));
}
}
Run Code Online (Sandbox Code Playgroud)
然后一个类将它混合在一起:
public class Customer : MXmlSerializable {
public string Name { get; set; }
public bool Preferred { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
用法很简单:
var customer = new Customer {
Name = "Guybrush Threepwood",
Preferred = true };
var xml = customer.ToXml();
Run Code Online (Sandbox Code Playgroud)
如果你喜欢这个想法,你可以为项目中有用的mixin创建一个新的命名空间.你怎么看?
哦,顺便说一句,我认为大多数扩展方法都应该明确地测试null.
这是我们的代码库中有趣的工作.在一个工作线程上走一个可枚举的昂贵的懒惰,并通过一个可观察的结果推回结果.
public static IObservable<T> ToAsyncObservable<T>(this IEnumerable<T> @this)
{
return Observable.Create<T>(observer =>
{
var task = new Task(() =>
{
try
{
@this.Run(observer.OnNext);
observer.OnCompleted();
}
catch (Exception e)
{
observer.OnError(e);
}
});
task.Start();
return () => { };
});
}
Run Code Online (Sandbox Code Playgroud)
傻样品:
new DirectoryInfo(@"c:\program files")
.EnumerateFiles("*", SearchOption.AllDirectories)
.ToAsyncObservable()
.BufferWithTime(TimeSpan.FromSeconds(0.5))
.ObserveOnDispatcher()
.Subscribe(
l => Console.WriteLine("{0} received", l.Count),
() => Console.WriteLine("Done!"));
for (;;)
{
Thread.Sleep(10);
Dispatcher.PushFrame(new DispatcherFrame());
}
Run Code Online (Sandbox Code Playgroud)
显然,如果您没有使用辉煌的Reactive Extensions,这个扩展对您来说将毫无用处!
更新感谢Richard在评论中,这种扩展方法是不必要的.RX已经有一个带有IScheduler的扩展方法"ToObservable".改用它!
这是我发现的另一对用于:
public static T ObjectWithMin<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
where T : class
where TResult : IComparable
{
if (!sequence.Any()) return null;
//get the first object with its predicate value
var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
//compare against all others, replacing the accumulator with the lesser value
//tie goes to first object found
return
sequence.Select(x => new {Object = x, Value = predicate(x)})
.Aggregate(seed,(acc, x) => acc.Value.CompareTo(x.Value) <= 0 ? acc : x).Object;
}
public static T ObjectWithMax<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
where T : class
where TResult : IComparable
{
if (!sequence.Any()) return null;
//get the first object with its predicate value
var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
//compare against all others, replacing the accumulator with the greater value
//tie goes to last object found
return
sequence.Select(x => new {Object = x, Value = predicate(x)})
.Aggregate(seed, (acc, x) => acc.Value.CompareTo(x.Value) > 0 ? acc : x).Object;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var myObject = myList.ObjectWithMin(x=>x.PropA);
Run Code Online (Sandbox Code Playgroud)
这些方法基本上取代了像
var myObject = myList.OrderBy(x=>x.PropA).FirstOrDefault(); //O(nlog(n)) and unstable
Run Code Online (Sandbox Code Playgroud)
和
var myObject = myList.Where(x=>x.PropA == myList.Min(x=>x.PropA)).FirstOrDefault(); //O(N^2) but stable
Run Code Online (Sandbox Code Playgroud)
和
var minValue = myList.Min(x=>x.PropA);
var myObject = myList.Where(x=>x.PropA == minValue).FirstOrDefault(); //not a one-liner, and though linear and stable it's slower (evaluates the enumerable twice)
Run Code Online (Sandbox Code Playgroud)
这是一个位图扩展,可以将位图转换为灰度;
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;
}
Run Code Online (Sandbox Code Playgroud)
样品用法:
Bitmap grayscaled = bitmap.GrayScale()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
124411 次 |
| 最近记录: |