简体   繁体   English

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

[英]What are your favorite extension methods for C#? (codeplex.com/extensionoverflow)

Let's make a list of answers where you post your excellent and favorite extension methods . 让我们列出一个答案列表,在其中发布优秀和最喜欢的扩展方法

The requirement is that the full code must be posted and a example and an explanation on how to use it. 要求是必须张贴完整的代码,并提供示例和使用说明。

Based on the high interest in this topic I have setup an Open Source Project called extensionoverflow on Codeplex . 基于对该主题的高度兴趣,我在Codeplex上建立了一个名为extensionoverflow的开源项目。

Please mark your answers with an acceptance to put the code in the Codeplex project. 请标记您的答案并接受,以将代码放入Codeplex项目。

Please post the full sourcecode and not a link. 请发布完整的源代码,而不发布链接。

Codeplex News: Codeplex新闻:

24.08.2010 The Codeplex page is now here: http://extensionoverflow.codeplex.com/ 24.08.2010现在,“ Codeplex”页面位于此处: http ://extensionoverflow.codeplex.com/

11.11.2008 XmlSerialize / XmlDeserialize is now Implemented and Unit Tested . 11.11.2008 XmlSerialize / XmlDeserialize现在已实现并进行了单元测试

11.11.2008 There is still room for more developers. 11.11.2008还有更多开发者的空间。 ;-) Join NOW! ;-) 立即加入!

11.11.2008 Third contributer joined ExtensionOverflow , welcome to BKristensen 11.11.2008第三位贡献者加入了ExtensionOverflow ,欢迎来到BKristensen

11.11.2008 FormatWith is now Implemented and Unit Tested . 11.11.2008 FormatWith现在已实现并进行了单元测试

09.11.2008 Second contributer joined ExtensionOverflow . 2008年9月11日第二位贡献者加入了ExtensionOverflow welcome to chakrit . 欢迎来到chakrit

09.11.2008 We need more developers. 2008年9月11日我们需要更多开发人员。 ;-) ;-)

09.11.2008 ThrowIfArgumentIsNull in now Implemented and Unit Tested on Codeplex. 09.11.2008 ThrowIfArgumentIsNull 在Codeplex上实现并进行了单元测试

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

Allows me to replace: 请允许我替换:

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

With: 带有:

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

I have various extension methods in my MiscUtil project (full source is available there - I'm not going to repeat it here). 我的MiscUtil项目中有多种扩展方法(那里提供完整的源代码-我在这里不再重复)。 My favourites, some of which involve other classes (such as ranges): 我的最爱,其中一些涉及其他类别(例如范围):

Date and time stuff - mostly for unit tests. 日期和时间的东西-主要用于单元测试。 Not sure I'd use them in production :) 不知道我会在生产中使用它们吗:)

var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();

Ranges and stepping - massive thanks to Marc Gravell for his operator stuff to make this possible: 范围和步伐-非常感谢Marc Gravell为他的操作员所做的一切:

var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());

Comparisons: 比较:

var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();

Argument checking: 参数检查:

x.ThrowIfNull("x");

LINQ to XML applied to anonymous types (or other types with appropriate properties): LINQ to XML应用于匿名类型(或具有适当属性的其他类型):

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

Push LINQ - would take too long to explain here, but search for it. 推送LINQ-在这里解释将花费很长时间,但是请进行搜索。

string.Format shortcut: 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);
    }
}

Example: 例:

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

For quick copy-and-paste go here . 要进行快速复制和粘贴,请转到此处

Don't you find it more natural to type "some string".F("param") instead of string.Format("some string", "param") ? 您是否发现键入"some string".F("param")而不是string.Format("some string", "param")更自然?

For a more readable name, try one of these suggestion: 有关更易读的名称,请尝试以下建议之一:

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

.. ..

Are these any use? 这些有用吗?

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

Example: 例:

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

The extension method: 扩展方法:

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

The method applies for all types and lets you add a range of items to a list as parameters. 该方法适用于所有类型,并允许您将一系列项作为参数添加到列表中。

Example: 例:

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

By all means put this in the codeplex project. 务必将其放在codeplex项目中。

Serializing / Deserializing objects to XML: 将对象序列化/反序列化为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.
    }
}

ForEach for IEnumerables IEnumerables的ForEach

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

Naive example: 天真的例子:

var buttons = GetListOfButtons() as IEnumerable<Button>;

// click all buttons
buttons.ForEach(b => b.Click());

Cool example: 很酷的例子:

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

Note: 注意:

This is not like Select because Select expects your function to return something as for transforming into another list. 这与Select因为Select 希望您的函数返回某些内容,就像转换到另一个列表一样。

ForEach simply allows you to execute something for each of the items without any transformations/data manipulation. ForEach仅允许您为每个项目执行某些操作,而无需任何转换/数据操作。

I made this so I can program in a more functional style and I was surprised that List has a ForEach while IEnumerable does not. 我这样做是为了可以以更实用的样式进行编程,但让List拥有ForEach而IEnumerable没有的却令我感到惊讶。

Put this in the codeplex project 把它放在codeplex项目中

My conversion extensions which allow you to do: 我的转化扩展程序可让您执行以下操作:

int i = myString.To<int>();

Here it is, as posted on TheSoftwareJedi.com 就像在TheSoftwareJedi.com上发布的一样

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

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

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

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

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

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

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

You can ask for default (calls blank constructor or "0" for numerics) on failure, specify a "default" value (I call it "other"), or ask for null (where T : class). 您可以在失败时请求默认值(调用空白构造函数或为数字调用“ 0”),指定“默认”值(我将其称为“其他”)或要求为null(其中T:class)。 I've also provided both silent exception models, and a typical TryParse model that returns a bool indicating the action taken, and an out param holds the new value. 我还提供了静默异常模型和典型的TryParse模型,该模型返回布尔值以指示所采取的操作,而out参数则保存新值。 So our code can do things like this 所以我们的代码可以做这样的事情

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

I couldn't get Nullable types to roll into the whole thing very cleanly. 我无法使Nullable类型非常整洁地融入整个过程。 I tried for about 20 minutes before I threw in the towel. 我试了约20分钟,然后才把毛巾扔了。

I have an extension method for logging exceptions: 我有一个记录异常的扩展方法:

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

And it is used like this: 它的用法是这样的:

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

[sorry for posting twice; [抱歉发布两次; the 2nd one is better designed :-)] 第二个是更好的设计:-)]

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

Useful to parse a string into an Enum. 将字符串解析为枚举很有用。

public enum TestEnum
{
    Bar,
    Test
}

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

Credit goes to Scott Dorman 归功于Scott Dorman

--- Edit for Codeplex project --- -编辑Codeplex项目-

I have asked Scott Dorman if he would mind us publishing his code in the Codeplex project. 我问过斯科特·多曼(Scott Dorman),他是否愿意我们在Codeplex项目中发布他的代码。 This is the reply I got from him: 这是我从他那里得到的答复:

Thanks for the heads-up on both the SO post and the CodePlex project. 感谢您对SO帖子和CodePlex项目的注意。 I have upvoted your answer on the question. 我已就你对这个问题的回答投票赞成。 Yes, the code is effectively in the public domain currently under the CodeProject Open License ( http://www.codeproject.com/info/cpol10.aspx ). 是的,该代码当前有效地处于CodeProject开放许可( http://www.codeproject.com/info/cpol10.aspx )下的公共领域中。

I have no problems with this being included in the CodePlex project, and if you want to add me to the project (username is sdorman) I will add that method plus some additional enum helper methods. 我将其包含在CodePlex项目中没有任何问题,如果您想将我添加到项目中(用户名是sdorman),我将添加该方法以及一些其他枚举帮助器方法。

I find this one pretty useful: 我发现这非常有用:

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

You may use it on CodePlex. 您可以在CodePlex上使用它。

DateTimeExtensions DateTimeExtensions

Examples: 例子:

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

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

Here is one I use frequently for presentation formatting. 这是我经常用于演示文稿格式化的一个。

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

Here's a to-and-from for Roman numerals. 这是罗马数字的往返。 Not often used, but could be handy. 不经常使用,但可能很方便。 Usage: 用法:

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

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

The source: 来源:

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

A convenient way to deal with sizes: 处理尺寸的便捷方法:

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

For Winform Controls: 对于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));
}

IsDesignTime Usage: 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 Usage: 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();

I forgot to mention, feel free to use these on Codeplex... 我忘了提,随时在Codeplex上使用这些...

The ThrowIfArgumentIsNull is a nice way to do that null check we all should do. 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");
    }
}

Below is the way to use it and it works on all classes in your namespace or wherever you use the namespace its within. 下面是使用它的方法,它可用于名称空间中的所有类或在其内部使用名称空间的任何位置。

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

It's ok to use this code on the CodePlex project. 可以在CodePlex项目上使用此代码。

I miss the Visual Basic's With statement when moving to C#, so here it goes: 移到C#时,我想念Visual Basic的With语句 ,所以就这样:

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

And here's how to use it in C#: 这是在C#中使用它的方法:

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

Saves a lot of typing! 节省大量打字!

Compare this to: 比较一下:

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

put in codeplex project 放入Codeplex项目

Takes a camelCaseWord or PascalCaseWord and "wordifies" it, ie camelCaseWord => camel Case Word 接受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])" ) );
}

I often use it in conjuction with Capitalize 我经常将其与Capitalize结合使用

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

Example usage 用法示例

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

Free to use in codeplex project 可在Codeplex项目中免费使用

I found this one helpful 我发现这有帮助

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

It removes the null check in the calling code. 它将删除调用代码中的空检查。 You could now do 你现在可以做

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

Convert a double to string formatted using the specified culture: 将双精度转换为使用指定区域性格式化的字符串:

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

Example: 例:

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

Below is an extension method that adapts Rick Strahl's code (and the comments too) to stop you having to guess or read the byte order mark of a byte array or text file each time you convert it to a string. 下面是一种扩展方法 ,该方法可以适应Rick Strahl的代码 (以及注释),以防止您每次将其转换为字符串时都不得不猜测或读取字节数组或文本文件的字节顺序标记。

The snippet allows you to simply do: 该代码段使您可以简单地执行以下操作:

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

If you find any bugs please add to the comments. 如果发现任何错误,请添加评论。 Feel free to include it in the Codeplex project. 随时将其包含在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();
            }
        }
    }
}

Here's one I just created today. 这是我今天刚刚创建的。

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

It lets you do this: 它可以让您做到这一点:

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

which is more fluent and (IMO) easier to read than this: 比这更流利,并且(IMO)更容易阅读:

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

I got tired of tedious null-checking while pulling values from MySqlDataReader, so: 从MySqlDataReader提取值时,我厌倦了繁琐的null检查,因此:

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

Of course this could be used with any SqlDataReader. 当然,这可以与任何SqlDataReader一起使用。


Both hangy and Joe had some good comments on how to do this, and I have since had an opportunity to implement something similar in a different context, so here is another version: hangy和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);
}

"Please mark your answers with an acceptance to put the code in the Codeplex project." “请在接受的答案上打上标记,以将代码放入Codeplex项目中。”

Why? 为什么? All the Stuff on this site under CC-by-sa-2.5 , so just put your Extension overflow Project under the same license and you can freely use it. 该站点上的所有Stuff均使用CC-by-sa-2.5 ,因此,只需将您的Extension Overflow Project置于相同的许可证下,即可自由使用它。

Anyway, here is a String.Reverse function, based on this question . 无论如何,这是基于此问题的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);
}

It irritated me that LINQ gives me an OrderBy that takes a class implementing IComparer as an argument, but does not support passing in a simple anonymous comparer function. LINQ给我带来了一个OrderBy,它使实现IComparer的类作为参数,但是不支持传递简单的匿名比较器函数,这使我感到恼火。 I rectified that. 我纠正了。

This class creates an IComparer from your comparer function... 此类从您的比较器函数创建一个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
}

...and these extension methods expose my new OrderBy overloads on enumerables. ...并且这些扩展方法暴露了我对枚举的新OrderBy重载。 I doubt this works for LINQ to SQL, but it's great for LINQ to Objects. 我怀疑这对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);
    }
}

You're welcome to put this on codeplex if you like. 如果愿意,可以将其放在Codeplex上。

This one is for MVC it adds the ability to generate a <label /> tag to the Html variable that is available in every ViewPage . 这是针对MVC的,它为在每个ViewPage可用的Html变量添加了生成<label />标记的ViewPage Hopefully it will be of use to others trying to develop similar extensions. 希望它对尝试开发类似扩展的其他人有用。

Use: 使用:

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

Output: 输出:

<label id="LabelId" for="ForId">Text</label>

Code: 码:

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

Turn this: 转这个:

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

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

command.Parameters.Add(param);

... into this: ...变成这样:

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

... using this extension method: ...使用此扩展方法:

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

More ADO.NET extension methods: DbExtensions 更多ADO.NET扩展方法: DbExtensions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM