当前位置:  开发笔记 > 编程语言 > 正文

你最喜欢的C#扩展方法是什么?(codeplex.com/extensionoverflow)

如何解决《你最喜欢的C#扩展方法是什么?(codeplex.com/extensionoverflow)》经验,为你挑选了57个好方法。

让我们列出你发布优秀和最喜欢的扩展方法的答案.

要求是必须发布完整代码并提供示例和如何使用它的说明.

基于对该主题的高度关注,我在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我们需要更多开发人员.;-)

09.11.2008 ThrowIfArgumentIsNull现在已在Codeplex上实现和单元测试.



1> Winston Smit..:
public static bool In(this T source, params T[] list)
{
  if(null==source) throw new ArgumentNullException("source");
  return list.Contains(source);
}

允许我替换:

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....
}

附:

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....
}


使用相同的Contains方法:(new [] {1,2,3}}.包含(a)
也许"EqualsAnyOf"比"In"更好名?
我不确定我喜欢它 - 我喜欢"In"的简洁,但也许"IsIn"会更好.
我还想到了`In (...)`,发现它是标准库之外最有用的扩展方法.但我与"In"这个名字不一致.方法名称应该描述它的作用,但是"In"不会这样做.我把它称为'IsAnyOf (...)`,但我想`IsIn (...)`也足够了.
好吧,如果你使用System.Linq,它会编译;

2> Jon Skeet..:

我在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应用于匿名类型(或具有适当属性的其他类型):

// Jon32
new { Name="Jon", Age=32}.ToXElements();
// Name="Jon" Age="32" (as XAttributes, obviously)
new { Name="Jon", Age=32}.ToXAttributes()

推LINQ - 在这里解释需要很长时间,但要搜索它.


这可能是不使用var的好时机.
@bovium:您已经可以看到代码了.按照第一句中的链接 - 完整的来源就在那里.

3> chakrit..:

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);
    }
}

例:

var s = "The co-ordinate is ({0}, {1})".F(point.X, point.Y);

要快速复制粘贴,请转到此处.

你不觉得打字更自然吗? "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");

..


好的......我只是把它付诸行动并且继续使用.With - 所以你得到"这是一个{0}".用("测试")并且它非常易读且有意义.FYI
它肯定很短 - 但对于团队的任何新成员来说都是不可读的.
就个人而言,我想要一个单独的Formatter对象,BCL可以解析一次的模式并重用.这将提高可读性和性能.我问过BCL团队 - 我们会看到......
我认为可读性在代码更宏大的方案中比在一些可以快速查找/询问的简写语句中更重要.
这是一种扩展方法,*当然*它对团队的新成员来说是不可读的.我觉得这个诙谐的东西就是这个想法?新成员怎么会知道我们有多聪明?
将"F"重命名为"FormatWith",它会更好.功能很好,但名称需要修复.
大约5个月前我加入了一个新团队,我看到这个愚蠢的".F"方法很多.当然他们拒绝改名字......

4> xyz..:

这些有用吗?

public static bool CoinToss(this Random rng)
{
    return rng.Next(2) == 0;
}

public static T OneOf(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!");


情侣:我建议`OneOf`应该接受*any*`IList `.然后你总是*也*有一个带有`params` arg的重载,只是将它传递给`IList `重载.我用一个类似于你的`CoinToss`的`NextBool`方法给出了一个答案(现在在底部向下),但是带有一个带有'概率'参数的重载(如果我希望在75%的时间内发生某些事情,那该怎么办? ?).另外,只是一个选择:你的示例代码将抛出一个`NullReferenceException`,因为`rand`永远不会被初始化.
+1我真的很喜欢这个,但我更喜欢``CoinToss`用`rng.NextDouble()<.5`实现,因为内部`.Next(int)`是用`.NextDouble()`做的,所以你会保存一个演员,a*和支票.

5> CMS..:
public static class ComparableExtensions
{
  public static bool Between(this T actual, T lower, T upper) where T : IComparable
  {
    return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
  }
}

例:

if (myNumber.Between(3,7))
{
  // ....
}


我喜欢这个,但我正在尝试决定是否正确检查包含最小值的边界但是对最大值是独占的.我想知道这是否会令人困惑.5.Between(5,10)之间是真的但5.Between(1,5)之间是假的.甚至不确定方法内的伴侣会有所帮助.Thougts?
对我来说暗示:5.Between(5,10)返回false,而10.Between(5,10)也返回false.这对我来说很自然.
"IsBetween"这个名字不是更有意义吗?也可以创建一个IsBetweenInclusive和IsBetweenExclusive.不知道哪一个默认采取.
在我看来,多个人对什么是自然的有不同的想法.因此,可能应明确说明正在使用的内容(即包含与排除),因为这可能是一个非常容易出错的来源.
@Steve:如果是日期时间扩展,那就更有意义了.

6> 小智..:

扩展方法:

public static void AddRange(this ICollection list, params S[] values)
    where S : T
{
    foreach (S value in values)
        list.Add(value);
}

该方法适用于所有类型,并允许您将一系列项目作为参数添加到列表中.

例:

var list = new List();
list.AddRange(5, 4, 8, 4, 2);


只需使用collection initializer =>`var list = new List {5,4,8,4,2};`
这个IList 会更好
@Will:实际上,接受一个`ICollection `是最好的*; 那么它也可以用于,例如,`LinkedList `和`HashSet `,而不仅仅是索引集合.
在pre -.net 4.0中编辑[允许协方差](http://stackoverflow.com/questions/1995113/strangest-language-feature/2004371#2004371)

7> TWith2Sugars..:

一定要把它放在codeplex项目中.

将对象序列化/反序列化为XML:

/// Serializes an object of type T in to an xml string
/// Any class type
/// Object to serialize
/// A string that represents Xml, empty otherwise
public static string XmlSerialize(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();
    }
}

/// Deserializes an xml string in to an object of Type T
/// Any class type
/// Xml as string to deserialize from
/// A new object of type T is successful, null if failed
public static T XmlDeserialize(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.
    }
}


我很想调用第一个`ToXml()`(就像`ToString()`)
请注意,这不是线程安全的.您绝对应该同步对静态序列化词典的访问权限.
@Yann,@ T,如果你只是添加"thread static"属性会容易得多.然后将为每个线程创建一个新的缓存.无需同步.

8> chakrit..:

ForEach for IEnumerables

public static class FrameworkExtensions
{
    // a map function
    public static void ForEach(this IEnumerable @enum, Action mapFunction)
    {
        foreach (var item in @enum) mapFunction(item);
    }
}

天真的例子:

var buttons = GetListOfButtons() as IEnumerable

很酷的例子:

// 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!";
    });

注意:

这不是Select因为Select 期望你的函数返回一些东西,就像转换到另一个列表一样.

ForEach只允许您为每个项执行某些操作而无需任何转换/数据操作.

我做了这个,所以我可以用更实用的风格编程,我很惊讶List有一个ForEach而IEnumerable没有.

把它放在codeplex项目中


发布为什么LINQ的IEnumerable 扩展不包含ForEach:http://stackoverflow.com/questions/317874/existing-linq-extension-method-similar-to-parallel-for/318493#318493
我建议在使用方法之前阅读此内容:http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx
@jpbochi:这只是微软的蛊惑人心

9> TheSoftwareJ..:

我的转换扩展程序允许您执行以下操作:

int i = myString.To();

这是,在TheSoftwareJedi.com张贴

public static T To(this IConvertible obj)
{
  return (T)Convert.ChangeType(obj, typeof(T));
}

public static T ToOrDefault
             (this IConvertible obj)
{
    try
    {
        return To(obj);
    }
    catch
    {
        return default(T);
    }
}

public static bool ToOrDefault
                    (this IConvertible obj,
                     out T newObj)
{
    try
    {
        newObj = To(obj); 
        return true;
    }
    catch
    {
        newObj = default(T); 
        return false;
    }
}

public static T ToOrOther
                       (this IConvertible obj,
                       T other)
{
  try
  {
      return Toobj);
  }
  catch
  {
      return other;
  }
}

public static bool ToOrOther
                         (this IConvertible obj,
                         out T newObj,
                         T other)
{
    try
    {
        newObj = To(obj);
        return true;
    }
    catch
    {
        newObj = other;
        return false;
    }
}

public static T ToOrNull
                      (this IConvertible obj)
                      where T : class
{
    try
    {
        return To(obj);
    }
    catch
    {
        return null;
    }
}

public static bool ToOrNull
                  (this IConvertible obj,
                  out T newObj)
                  where T : class
{
    try
    {
        newObj = To(obj);
        return true;
    }
    catch
    {
        newObj = null;
        return false;
    }
}

您可以在失败时请求默认值(调用空白构造函数或"0"表示数字),指定"默认"值(我称之为"其他"),或者请求null(其中T:class).我还提供了两个静默异常模型,以及一个返回bool的典型TryParse模型,指示所采取的操作,out参数保存新值.所以我们的代码可以做这样的事情

int i = myString.To();
string a = myInt.ToOrDefault();
//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();

我无法让Nullable类型非常干净地滚动到整个事物中.在我扔掉毛巾之前,我试了大约20分钟.


就个人而言,我不是尝试/捕获确定结果的代码的粉丝.对于在预期逻辑IMO之外发生的错误,应该使用try/catch.hmmmmm
您至少应该更改"catch"子句,以便仅捕获ChangeType()在无法"转换"引用时将引发的异常.我想你不希望任何OutOfMemoryException,ExecutionEngineException,ThreadAbortException或类似的被视为转换错误.否则,这些事情很难跟踪错误.
我相信`ToOrNull`与`ToOrDefault`具有完全相同的行为(即,如果你在转换失败的引用类型上调用`ToOrDefault`,它将返回`null`).但更重要的是,它对我来说似乎有点多余,因为`var s = myObject as string`完成与`var s = myObject.ToOrNull ()`相同的事情 - 但是没有必要捕获`InvalidCastException` .我错过了什么吗?

10> 小智..:

我有一个记录异常的扩展方法:

public static void Log(this Exception obj)
{
  //your logging logic here
}

它使用如下:

try
{
    //Your stuff here
}
catch(Exception ex)
{
    ex.Log();
}

[抱歉发布两次; 第二个是更好的设计:-)]


应该读取public static void Log(这个异常obj){}吗?

11> mlarsen..:
public static class StringExtensions {

    /// 
    /// Parses a string into an Enum
    /// 
    /// The type of the Enum
    /// String value to parse
    /// The Enum corresponding to the stringExtensions
    public static T EnumParse(this string value) {
        return StringExtensions.EnumParse(value, false);
    }

    public static T EnumParse(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);
    }
}

用于将字符串解析为枚举.

public enum TestEnum
{
    Bar,
    Test
}

public class Test
{
    public void Test()
    {
        TestEnum foo = "Test".EnumParse();
    }
 }

幸得斯科特·多尔曼

---编辑Codeplex项目---

我问Scott Dorman是否会介意我们在Codeplex项目中发布他的代码.这是我从他那里得到的答复:

感谢SO帖子和CodePlex项目的单挑.我对这个问题提出了答案.是的,该代码实际上属于CodeProject Open License(http://www.codeproject.com/info/cpol10.aspx)下的公共域.

我在CodePlex项目中包含它没有任何问题,如果你想将我添加到项目中(用户名是sdorman),我将添加该方法以及一些额外的枚举助手方法.


您也可以考虑命名此ToEnum <>(),因为它位于对象之后.

12> Juliet..:

我发现这个非常有用:

public static class PaulaBean
{
    private static String paula = "Brillant";
    public static String GetPaula(this T obj) {
        return paula;
    }
}

您可以在CodePlex上使用它.


有人可以善待我们向那些不那么有天赋的人解释吗?

13> CMS..:

DateTimeExtensions

例子:

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();


DateTime.Now.First() - 首先是什么?从示例代码中可以看出这一点.
我建议将"SetTime"重命名为"WithTime",因为它实际上并没有将它设置为现有值.不过不错.
非常好.但同意这些名字可能要好得多.

14> sontek..:

gitorious.org/cadenza是我见过的一些最有用的扩展方法的完整库.


我们能有例子吗?

15> Venr..:

这是我经常用于演示文稿格式化的一个.

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());
}



16> Jesse C. Sli..:

这是罗马数字的来往.不经常使用,但可能很方便.用法:

if ("IV".IsValidRomanNumeral())
{
   // Do useful stuff with the number 4.
}

Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());

来源:

    public static class RomanNumeralExtensions
    {
        private const int NumberOfRomanNumeralMaps = 13;

        private static readonly Dictionary romanNumerals =
            new Dictionary(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();
        }
    }



17> Paolo Tedesc..:

处理尺寸的便捷方式:

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
        };
    }
}



18> fre0n..:

对于Winform控件:

/// 
/// Returns whether the function is being executed during design time in Visual Studio.
/// 
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;
}

/// 
/// Sets the DropDownWidth to ensure that no item's text is cut off.
/// 
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));
}

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
    }
}

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();

我忘了提及,随意在Codeplex上使用这些...



19> bovium..:

ThrowIfArgumentIsNull是一个很好的方法来做我们都应该做的空检查.

public static class Extensions
{
    public static void ThrowIfArgumentIsNull(this T obj, string parameterName) where T : class
    {
        if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
    }
}

下面是使用它的方法,它适用于命名空间中的所有类或在其中使用命名空间的任何位置.

internal class Test
{
    public Test(string input1)
    {
        input1.ThrowIfArgumentIsNull("input1");
    }
}

可以在CodePlex项目上使用此代码.


如果使用仅带有1个字符串参数的ArgumentNullException构造函数,则该参数必须只是参数名称,而不是错误消息.所以你的代码应该是这样的:if(obj == null)抛出新的ArgumentNullException(parameterName);

20> chakrit..:

移动到C#时,我想念Visual Basic的With语句,所以这里:

public static void With(this T obj, Action act) { act(obj); }

以下是如何在C#中使用它:

someVeryVeryLonggggVariableName.With(x => {
    x.Int = 123;
    x.Str = "Hello";
    x.Str2 = " World!";
});

节省了很多打字!

比较这个:

someVeryVeryLonggggVariableName.Int = 123;
someVeryVeryLonggggVariableName.Str = "Hello";
someVeryVeryLonggggVariableName.Str2 = " World!";

放入codeplex项目


我还尽可能使用c#3.0属性初始化程序语法来实现相同的结果.
只是一个猜测,但想想如果你的T是一个结构会发生什么.
@chakrit,这是一个例子.它仅适用于创建对象时按钮n = new Button {Name ="Button1",Width = 100,Height = 20,Enabled = true};

21> µBio..:

采用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, @"(?

我经常将它与Capitalize结合使用

public static string Capitalize( this string word )
{
    return word[0].ToString( ).ToUpper( ) + word.Substring( 1 );
}

用法示例

SomeEntityObject entity = DataAccessObject.GetSomeEntityObject( id );
List properties = entity.GetType().GetPublicNonCollectionProperties( );

// wordify the property names to act as column headers for an html table or something
List columns = properties.Select( p => p.Name.Capitalize( ).Wordify( ) ).ToList( );

免费在codeplex项目中使用



22> Vasu Balakri..:

我发现这个有用

public static IEnumerable EmptyIfNull(this IEnumerable pSeq)
{
    return pSeq ?? Enumerable.Empty();
}

它删除了调用代码中的空检查.你现在可以做

MyList.EmptyIfNull().Where(....)



23> CMS..:

将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));
  }
}

例:

double test = 154.20;
string testString = test.ToCurrency("en-US"); // $154.20


你应该使用十进制货币,否则你会得到四舍五入的问题

24> Chris S..:

下面是一个扩展方法,它适应Rick Strahl的代码(以及注释),以阻止您每次将其转换为字符串时猜测或读取字节数组或文本文件的字节顺序标记.

该片段允许您简单地执行:

byte[] buffer = File.ReadAllBytes(@"C:\file.txt");
string content = buffer.GetString();

如果您发现任何错误,请添加评论.随意将其包含在Codeplex项目中.

public static class Extensions
{
    /// 
    /// 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
    /// 
    /// An array of bytes to convert
    /// The byte as a string.
    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();
            }
        }
    }
}



25> scobi..:

这是我今天刚刚创建的.

// requires .NET 4

public static TReturn NullOr(this TIn obj, Func 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(this TIn obj, Func func,
        TReturn elseValue) where TIn : class
    { return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr(this TIn obj, Func func)
        where TIn : class
    { return obj != null ? func(obj) : default(TReturn); }

它可以让你这样做:

var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());

哪个更流畅,(IMO)更容易阅读比这个:

var lname = (thingy != null ? thingy.Name : null) != null
    ? thingy.Name.ToLower() : null;


应该要求TIn是一个类,否则这整个扩展方法没有意义(值类型不能为null).使用t.Count的示例可以使用上面的扩展方法.你能再看一眼吗?

26> Adam Lassek..:

在从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);
}

当然,这可以与任何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);
}


这也应该作为IDataReader的扩展方法.
实际上,请使用IDataRecord类型的"this"参数以获得最大兼容性.在我的这个版本中,我有一个带有序号的重载,fieldName版本调用它.保存"GetOrdinal",然后按名称查找.

27> Michael Stum..:

"请在接受将代码放入Codeplex项目时标记您的答案."

为什么?这个网站上的所有东西都在CC-by-sa-2.5下,所以只需将你的扩展溢出项目置于相同的许可下,你就可以自由使用它了.

无论如何,这是一个String.Reverse函数,基于这个问题.

/// 
/// Reverse a String
/// 
/// The string to Reverse
/// The reversed String
public static string Reverse(this string input)
{
    char[] array = input.ToCharArray();
    Array.Reverse(array);
    return new string(array);
}


希望您不会遇到任何代理人或组合人物.

28> Joel Mueller..:

令我恼火的是,LINQ给了我一个OrderBy,它接受一个实现IComparer作为参数的类,但不支持传入一个简单的匿名比较器函数.我纠正了这一点.

这个类从比较器函数创建一个IComparer ...

/// 
///     Creates an  instance for the given
///     delegate function.
/// 
internal class ComparerFactory : IComparer
{
    public static IComparer Create(Func comparison)
    {
        return new ComparerFactory(comparison);
    }

    private readonly Func _comparison;

    private ComparerFactory(Func comparison)
    {
        _comparison = comparison;
    }

    #region IComparer Members

    public int Compare(T x, T y)
    {
        return _comparison(x, y);
    }

    #endregion
}

...并且这些扩展方法在枚举上公开了我的新OrderBy重载.我怀疑它适用于LINQ to SQL,但它对于LINQ to Objects非常有用.

public static class EnumerableExtensions
{
    /// 
    /// Sorts the elements of a sequence in ascending order by using a specified comparison delegate.
    /// 
    public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector,
                                                                     Func comparison)
    {
        var comparer = ComparerFactory.Create(comparison);
        return source.OrderBy(keySelector, comparer);
    }

    /// 
    /// Sorts the elements of a sequence in descending order by using a specified comparison delegate.
    /// 
    public static IOrderedEnumerable OrderByDescending(this IEnumerable source, Func keySelector,
                                                                               Func comparison)
    {
        var comparer = ComparerFactory.Create(comparison);
        return source.OrderByDescending(keySelector, comparer);
    }
}

如果你愿意,欢迎你把它放在codeplex上.



29> Eric Schoono..:

这个适用于MVC,它增加了为每个可用Html变量生成标记的功能ViewPage.希望它对试图开发类似扩展的其他人有用.

使用:

<%= Html.Label("LabelId", "ForId", "Text")%>

输出:


码:

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 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 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);
    }
}



30> Max Toro..:

转过来:

DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT @param";

DbParameter param = command.CreateParameter();
param.ParameterName = "@param";
param.Value = "Hello World";

command.Parameters.Add(param);

......进入这个:

DbCommand command = connection.CreateCommand("SELECT {0}", "Hello World");

...使用此扩展方法:

using System;
using System.Data.Common;
using System.Globalization;
using System.Reflection;

namespace DbExtensions {

   public static class Db {

      static readonly Func getDbProviderFactory;
      static readonly Func getParameterName;
      static readonly Func getParameterPlaceholder;

      static Db() {

         getDbProviderFactory = (Func)Delegate.CreateDelegate(typeof(Func), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
         getParameterName = (Func)Delegate.CreateDelegate(typeof(Func), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
         getParameterPlaceholder = (Func)Delegate.CreateDelegate(typeof(Func), 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;
      }
   }
}

更多ADO.NET扩展方法:DbExtensions



31> mattmc3..:

我最喜欢的一个是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

这是代码

public static class StringEntentions {
    /// 
    /// Indicates whether the current string matches the supplied wildcard pattern.  Behaves the same
    /// as VB's "Like" Operator.
    /// 
    /// The string instance where the extension method is called
    /// The wildcard pattern to match.  Syntax matches VB's Like operator.
    /// true if the string matches the supplied pattern, false otherwise.
    /// See http://msdn.microsoft.com/en-us/library/swf8kaxw(v=VS.100).aspx
    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;
    }
}



32> 小智..:

在此处查找更多示例:www.extensionmethod.net



33> johnc..:

类似于上面的字符串As和Is,但是对所有对象都是全局的.

这很简单,但是我用这些来减轻拳击的parens爆炸.

public static class ExtensionMethods_Object
{
    [DebuggerStepThrough()]
    public static bool Is(this object item) where T : class
    {
        return item is T;
    }

    [DebuggerStepThrough()]
    public static bool IsNot(this object item) where T : class
    {
        return !(item.Is());
    }

    [DebuggerStepThrough()]
    public static T As(this object item) where T : class
    {
        return item as T;
    }
}

我很高兴这个代码在codeplex中使用,实际上它已经是.


@Kamarey这是一个主观偏好,但它可以减少在你有多个演员阵容时可能会产生的混乱局面.如果您需要使用项目作为强制类型,则类型变为(项目类型)或((类型)项目).另外,从左到右扫描item.As ()....在一些令人困惑的情况下,比拳击更具可读性.我确实说它很简单,我同意它是主观的,但我发现它在代码可读性方面非常强大.

34> TWith2Sugars..:

对我来说另一个有用的:

/// 
/// Converts any type in to an Int32
/// 
/// Any Object
/// Value to convert
/// The integer, 0 if unsuccessful
public static int ToInt32(this T value)
{
  int result;
  if (int.TryParse(value.ToString(), out result))
  {
    return result;
  }
  return 0;
}

/// 
/// Converts any type in to an Int32 but if null then returns the default
/// 
/// Value to convert
/// Any Object
/// Default to use
/// The defaultValue if unsuccessful
public static int ToInt32(this T value, int defaultValue)
{
  int result;
  if (int.TryParse(value.ToString(), out result))
  {
    return result;
  }
  return defaultValue;
}

例:

int number = "123".ToInt32();

要么:

int badNumber = "a".ToInt32(100); // Returns 100 since a is nan


Convert.ToInt32(对象)?
如果我记得正确转换.ToIt32可能会抛出异常

35> jpbochi..:

IEnumerable<> 拖曳

我用Fisher-Yates算法实现了一个shuffle函数.

通过yield return在两个函数中使用和破坏代码,它实现了正确的参数验证延迟执行.(谢谢Dan,我在第一个版本中指出了这个缺陷)

static public IEnumerable Shuffle(this IEnumerable source)
{
    if (source == null) throw new ArgumentNullException("source");

    return ShuffleIterator(source);
}

static private IEnumerable ShuffleIterator(this IEnumerable 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;
}



36> Dan Tao..:

你可以从Random课堂上获得很多功能.

以下是我不时使用的一些扩展方法.有了这些,除了NextNextDouble中,Random类为您NextBool,NextChar,NextDateTime,NextTimeSpan,NextDouble(接受minValuemaxValue参数),以及我个人最喜欢的: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);
    }
}



37> Jay Bazuzi..:

我很失望.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));
}

是的,你可以把它放在codeplex中



38> 小智..:

一些我最好的方法扩展(我有很多!):

public static T ToEnum(this string str) where T : struct
{
    return (T)Enum.Parse(typeof(T), str);
}

//DayOfWeek sunday =  "Sunday".ToEnum();

public static string ToString(this IEnumerable collection, string separator)
{
    return ToString(collection, t => t.ToString(), separator);
}

public static string ToString(this IEnumerable collection, Func 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"

此外,接下来的几乎意味着能够在几乎任何情况下继续在同一行,而不是声明新的变量,然后删除状态:

public static R Map(this T t, Func func)
{
    return func(t);
}

ExpensiveFindWally().Map(wally=>wally.FirstName + " " + wally.LastName)

public static R TryCC(this T t, Func func)
    where T : class
    where R : class
{
    if (t == null) return null;
    return func(t);
}

public static R? TryCS(this T t, Func func)
    where T : class
    where R : struct
{
    if (t == null) return null;
    return func(t);
}

public static R? TryCS(this T t, Func func)
    where T : class
    where R : struct
{
    if (t == null) return null;
    return func(t);
}

public static R TrySC(this T? t, Func func)
    where T : struct
    where R : class
{
    if (t == null) return null;
    return func(t.Value);
}

public static R? TrySS(this T? t, Func func)
    where T : struct
    where R : struct
{
    if (t == null) return null;
    return func(t.Value);
}

public static R? TrySS(this T? t, Func 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(this T? t, string mensaje)
    where T : struct
{
    if (t == null)
        throw new NullReferenceException(mensaje);
    return t.Value;
}

public static T ThrowIfNullC(this T t, string mensaje)
    where T : class
{
    if (t == null)
        throw new NullReferenceException(mensaje);
    return t;
}

public static T Do(this T t, Action action)
{
    action(t);
    return t;
}

//Button b = new Button{Content = "Click"}.Do(b=>Canvas.SetColumn(b,2));

public static T TryDo(this T t, Action action) where T : class
{
    if (t != null)
        action(t);
    return t;
}

public static T? TryDoS(this T? t, Action action) where T : struct
{
    if (t != null)
        action(t.Value);
    return t;
}

希望它看起来不像来自火星:)



39> Rinat Abdull..:

与Timespan相关的扩展,例如:

public static TimeSpan Seconds(this int seconds)
{
  return TimeSpan.FromSeconds(seconds);
}

public static TimeSpan Minutes(this int minutes)
{
  return TimeSpan.FromMinutes(minutes);
}

允许使用:

1.Seconds()
20.Minutes()

锁定扩展名如:

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);
}

允许使用锁定:

using (lock.GetUpgradeableReadLock())
{
  // try read
  using (lock.GetWriteLock())
  {
    //do write
  }
}

以及Lokad共享图书馆的其他许多内容



40> Konamiman..:

我在Silverlight项目中使用这些:

public static void Show(this UIElement element)
{
    element.Visibility = Visibility.Visible;
}

public static void Hide(this UIElement element)
{
    element.Visibility = Visibility.Collapsed;
}



41> Pure.Krome..:

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(this IEnumerable iEnumerable)
        {
            // Cheers to Joel Mueller for the bugfix. Was .Count(), now it's .Any()
            return iEnumerable == null ||
                   !iEnumerable.Any();
        }

        public static IList ToListIfNotNullOrEmpty(this IList iList)
        {
            return iList.IsNullOrEmpty() ? null : iList;
        }

        public static PagedList ToPagedListIfNotNullOrEmpty(this PagedList 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(" ", "_");
        }
    }
}


在IsNullOrEmpty上,我讨厌在一个百万项的枚举器上调用它.它会循环遍历所有百万项,只是为了告诉我它不是空的.更好:返回iEnumerable == null || !iEnumerable.Any();

42> TraumaPony..:
public static class EnumerableExtensions
{
    [Pure]
    public static U MapReduce(this IEnumerable enumerable, Func map, Func 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(this IList list, Func map, Func 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(this IList list, Func map, Func 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;
    }

}


通过在合同检查中调用"Count"来枚举"可枚举"是不是有点危险?或者这不是运行时检查?

43> Kenny Eliass..:

有时,使用自定义分隔符在列表中的选定元素上写出字符串非常方便.

例如,如果你有一个List并想要用逗号分隔出姓氏,你可以这样做.

string result = string.Empty;
foreach (var person in personList) {
   result += person.LastName + ", ";
}
result = result.Substring(0, result.Length - 2);
return result;

或者你可以使用这个方便的扩展方法

public static string Join(this IEnumerable collection, Func func, string separator)
{
  return String.Join(separator, collection.Select(func).ToArray());
}

并像这样使用它

personList.Join(x => x.LastName, ", ");

它产生相同的结果,在这种情况下是由逗号分隔的姓氏列表.



44> Thomas Leves..:

二进制搜索:

public static T BinarySearch(this IList list, Func keySelector, TKey key)
        where TKey : IComparable
{
    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");
}

用法(假设列表按Id排序):

var item = list.BinarySearch(i => i.Id, 42);

抛出InvalidOperationException这一事实可能看起来很奇怪,但这就是Enumerable.First在没有匹配项时所做的事情.



45> Mark Rushako..:

到目前为止,我刚刚浏览了所有这4页,我感到非常惊讶,因为我没有看到这种缩短支票的方法InvokeRequired:

using System;
using System.Windows.Forms;

/// 
/// Extension methods acting on Control objects.
/// 
internal static class ControlExtensionMethods
{
    /// 
    /// Invokes the given action on the given control's UI thread, if invocation is needed.
    /// 
    /// Control on whose UI thread to possibly invoke.
    /// Action to be invoked on the given control.
    public static void MaybeInvoke(this Control control, Action action)
    {
        if (control != null && control.InvokeRequired)
        {
            control.Invoke(action);
        }
        else
        {
            action();
        }
    }

    /// 
    /// Maybe Invoke a Func that returns a value.
    /// 
    /// Return type of func.
    /// Control on which to maybe invoke.
    /// Function returning a value, to invoke.
    /// The result of the call to func.
    public static T MaybeInvoke(this Control control, Func func)
    {
        if (control != null && control.InvokeRequired)
        {
            return (T)(control.Invoke(func));
        }
        else
        {
            return func();
        }
    }
}

用法:

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));



46> benPearce..:

一些日期功能:

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);
}



47> bruno conde..:

通过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"));

码:

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));
    }
}


你不应该关闭那些文件句柄吗?
这不是使用扩展方法.它只是一个静态类.

48> Zack Elan..:

词典的Pythonic方法:

/// 
/// If a key exists in a dictionary, return its value, 
/// otherwise return the default value for that type.
/// 
public static U GetWithDefault(this Dictionary dict, T key)
{
    return dict.GetWithDefault(key, default(U));
}

/// 
/// If a key exists in a dictionary, return its value,
/// otherwise return the provided default value.
/// 
public static U GetWithDefault(this Dictionary dict, T key, U defaultValue)
{
    return dict.ContainsKey(key)
        ? dict[key]
        : defaultValue;
}

当您想要将时间戳附加到文件名以确保唯一性时很有用.

/// 
/// Format a DateTime as a string that contains no characters
//// that are banned from filenames, such as ':'.
/// 
/// YYYY-MM-DD_HH.MM.SS
public static string ToFilenameString(this DateTime dt)
{
    return dt.ToString("s").Replace(":", ".").Replace('T', '_');
}


更好地使用TryGetValue,您正在进行两次查找而不是一次查找.

49> 小智..:

我通常使用这种扩展方法使用匿名类型来获取字典ala ruby

public static Dictionary ToDictionary(this object o)
{
    var dictionary = new Dictionary();

    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 dict = dummy.ToDictionary();

并采用扩展方法

public static void ForEach(this IEnumerable source, Action 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'



50> John Leidegr..:

我发现自己一遍又一遍地这样做......

public static bool EqualsIgnoreCase(this string a, string b)
{
    return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}

......接着StartsWithIgnoreCase,EndsWithIgnoreCaseContainsIgnoreCase.



51> si618..:

使用密钥为字符串的字典时,使用不区分大小写的搜索返回现有密钥.我们的用例是文件路径.

/// 
/// Gets the key using  from .
/// 
/// The dictionary value.
/// The dictionary.
/// The case insensitive key.
/// 
/// An existing key; or  if not found.
/// 
public static string GetKeyIgnoringCase(this IDictionary 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;
}


字典中有一个单独的键集合属性,可以更快地完成此操作
如果需要不区分大小写的键,则可以将StringComparer.InvariantIgnoreCase传递给字典构造函数

52> Mark Cidade..:
static string Format( this string str,
                    , params Expression>[] 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();
}

使用上面的扩展名你可以这样写:

var str = "{foo} {bar} {baz}".Format(foo=>foo, bar=>2, baz=>new object());

你会得到"foo 2 System.Object".



53> Mark Maxham..:

简单但比"Enumerable.Range"更好,恕我直言:

/// 
/// Replace "Enumerable.Range(n)" with "n.Range()":
/// 
/// iterations
/// 0..n-1
public static IEnumerable Range(this int n)
{
    for (int i = 0; i < n; i++)
        yield return i;
}



54> Jordão..:

您可能已经知道扩展方法的一个有趣用法是作为一种混合.一些扩展方法,如XmlSerializable,几乎每个类都污染; 它对大多数人来说没有意义,比如ThreadSqlConnection.

应该将某些功能明确地混合到想要拥有它的类中.我提出了这种类型的新表示法,带有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(string xml) where T : MXmlSerializable {
    var serializer = new XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(new StringReader(xml));
  }
}

然后一个类将它混合在一起:

public class Customer : MXmlSerializable {
  public string Name { get; set; }
  public bool Preferred { get; set; }
}

用法很简单:

var customer = new Customer { 
  Name = "Guybrush Threepwood", 
  Preferred = true };
var xml = customer.ToXml();

如果你喜欢这个想法,你可以为项目中有用的mixin创建一个新的命名空间.你怎么看?

哦,顺便说一句,我认为大多数扩展方法都应该明确地测试null.



55> scobi..:

这是我们的代码库中有趣的工作.在一个工作线程上走一个可枚举的昂贵的懒惰,并通过一个可观察的结果推回结果.

public static IObservable ToAsyncObservable(this IEnumerable @this)
{
    return Observable.Create(observer =>
    {
        var task = new Task(() =>
        {
            try
            {
                @this.Run(observer.OnNext);
                observer.OnCompleted();
            }
            catch (Exception e)
            {
                observer.OnError(e);
            }
        });

        task.Start();

        return () => { };
    });
}

傻样品:

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());
}

显然,如果您没有使用辉煌的Reactive Extensions,这个扩展对您来说将毫无用处!

更新感谢Richard在评论中,这种扩展方法是不必要的.RX已经有一个带有IScheduler的扩展方法"ToObservable".改用它!


任何原因`enumerable.ToObservable(Scheduler.TaskPool)`都没有解决同样的问题?

56> KeithS..:

这是我发现的另一对用于:

public static T ObjectWithMin(this IEnumerable sequence, Func 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(this IEnumerable sequence, Func 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;
}

用法:

var myObject = myList.ObjectWithMin(x=>x.PropA);

这些方法基本上取代了像

var myObject = myList.OrderBy(x=>x.PropA).FirstOrDefault(); //O(nlog(n)) and unstable

var myObject = myList.Where(x=>x.PropA == myList.Min(x=>x.PropA)).FirstOrDefault(); //O(N^2) but stable

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)



57> HuseyinUslu..:

这是一个位图扩展,可以将位图转换为灰度;

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()

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有