Какие ваши любимые методы расширения для C #? (Codeplex.com/extensionoverflow)

Для тех, кто хочет знать, что события, связанные с последовательностью, вызываются, см. ниже. Пока что я тестировал только в Chrome.

  1. mouseover
  2. mousemove
  3. mouseout

  1. mousedown
  2. изменение (на сфокусированном входе)
  3. размытие (на сфокусированном элементе)
  4. фокус
  5. mouseup
  6. нажмите
  7. dblclick

  1. keydown
  2. keypress
  3. keyup
478
задан 31 revs, 9 users 41% 23 May 2017 в 12:18
поделиться

115 ответов

WhereIf () Метод

var query = dc.Reviewer 
    .Where(r => r.FacilityID == facilityID) 
    .WhereIf(CheckBoxActive.Checked, r => r.IsActive); 

public static IEnumerable<TSource> WhereIf<TSource>(
    this IEnumerable<TSource> source,
    bool condition, Func<TSource, bool> predicate) 
{ 
    if (condition) 
        return source.Where(predicate); 
    else 
        return source; 
}

public static IQueryable<TSource> WhereIf<TSource>(
    this IQueryable<TSource> source,
    bool condition, Expression<Func<TSource, bool>> predicate) 
{ 
    if (condition) 
        return source.Where(predicate); 
    else 
        return source; 
}

я также добавил перегрузки для индексного предиката в Где () дополнительный метод. Для большего количества забавы добавьте разновидность, которая 'еще' включает дополнительное предикат.

1
ответ дан andleer 23 May 2017 в 22:18
поделиться

Встроенные Преобразования: Мне нравится этот небольшой шаблон. Завершенный это для булевской переменной и DateTime. Разработанный для следования за C# и как операторы.

public static Int32? AsInt32(this string s)
{
    Int32 value;
    if (Int32.TryParse(s, out value))
        return value;

    return null;
}

public static bool IsInt32(this string s)
{
    return s.AsInt32().HasValue;
}

public static Int32 ToInt32(this string s)
{
    return Int32.Parse(s);
{
1
ответ дан 2 revs 23 May 2017 в 22:18
поделиться
  • 1
    @Christian: у Меня было более раннее редактирование, которое пропустило комментарий в его коде. Я удалил его из своего ответа. Griwes, по-видимому, поймал его, прежде чем я сделал. – Dave S 14 October 2011 в 13:22
public static bool In<T>(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....
}
232
ответ дан 22 November 2019 в 22:47
поделиться

Меня раздражало, что LINQ дает мне OrderBy, который принимает в качестве аргумента класс, реализующий IComparer, но не поддерживает передачу простой анонимной функции сравнения. Я исправил это.

Этот класс создает IComparer из вашей функции сравнения ...

/// <summary>
///     Creates an <see cref="IComparer{T}"/> instance for the given
///     delegate function.
/// </summary>
internal class ComparerFactory<T> : IComparer<T>
{
    public static IComparer<T> Create(Func<T, T, int> comparison)
    {
        return new ComparerFactory<T>(comparison);
    }

    private readonly Func<T, T, int> _comparison;

    private ComparerFactory(Func<T, T, int> comparison)
    {
        _comparison = comparison;
    }

    #region IComparer<T> Members

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

    #endregion
}

... и эти методы расширения предоставляют мои новые перегрузки OrderBy для перечисляемых объектов. Я сомневаюсь, что это работает для LINQ to SQL, но он отлично подходит для LINQ to Objects.

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

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

Вы можете поместить это в codeplex, если хотите.

14
ответ дан 22 November 2019 в 22:47
поделиться

Я нашел это полезным

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

Он удаляет нулевую проверку в вызывающем коде. Теперь вы можете выполнить

MyList.EmptyIfNull().Where(....)
17
ответ дан 22 November 2019 в 22:47
поделиться

Ниже приведен метод расширения , который адаптирует код Рика Страла (и комментарии тоже), чтобы вам не приходилось угадывать или читать метку порядка байтов. массива байтов или текстового файла каждый раз, когда вы конвертируете его в строку.

Этот фрагмент позволяет вам просто сделать:

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

Если вы обнаружите какие-либо ошибки, добавьте их в комментарии. Не стесняйтесь включать его в проект 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();
            }
        }
    }
}
15
ответ дан 22 November 2019 в 22:47
поделиться

Я нахожу этот довольно полезно:

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

Вы можете использовать его на CodePlex.

32
ответ дан 22 November 2019 в 22:47
поделиться

Превратите это:

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

Другие методы расширения ADO.NET : DbExtensions

12
ответ дан 22 November 2019 в 22:47
поделиться

Для элементов управления 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:

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

24
ответ дан 22 November 2019 в 22:47
поделиться

Иногда удобно записать строку для выбранного элемента в списке с помощью настраиваемого разделителя.

Например, если у вас есть 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<T>(this IEnumerable<T> collection, Func<T, string> func, string separator)
{
  return String.Join(separator, collection.Select(func).ToArray());
}

И использовать его так

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

Что дает тот же результат, в данном случае список фамилий, разделенных через запятую.

7
ответ дан 22 November 2019 в 22:47
поделиться

Я использую их в своих проектах Silverlight:

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

public static void Hide(this UIElement element)
{
    element.Visibility = Visibility.Collapsed;
}
8
ответ дан 22 November 2019 в 22:47
поделиться

Двоичный поиск:

public static T BinarySearch<T, TKey>(this IList<T> list, Func<T, TKey> keySelector, TKey key)
        where TKey : IComparable<TKey>
{
    int min = 0;
    int max = list.Count;
    int index = 0;
    while (min < max)
    {
        int mid = (max + min) / 2;
        T midItem = list[mid];
        TKey midKey = keySelector(midItem);
        int comp = midKey.CompareTo(key);
        if (comp < 0)
        {
            min = mid + 1;
        }
        else if (comp > 0)
        {
            max = mid - 1;
        }
        else
        {
            return midItem;
        }
    }
    if (min == max &&
        keySelector(list[min]).CompareTo(key) == 0)
    {
        return list[min];
    }
    throw new InvalidOperationException("Item not found");
}

Использование (при условии, что список отсортирован по Id):

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

Тот факт, что он генерирует исключение InvalidOperationException, может показаться странным, но именно это делает Enumerable.First, когда нет подходящего элемента.

7
ответ дан 22 November 2019 в 22:47
поделиться

IEnumerable <> Перемешать

I использовал алгоритм Фишера-Йейтса для реализации функции перемешивания.

Используя yield return и разбивая код на две функции, достигается правильная проверка аргумента и отложенное выполнение . (спасибо, Дэн , за указание на этот недостаток в моей первой версии)

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

    return ShuffleIterator(source);
}

static private IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source)
{
    T[] array = source.ToArray();
    Random rnd = new Random();          
    for (int n = array.Length; n > 1;)
    {
        int k = rnd.Next(n--); // 0 <= k < n

        //Swap items
        if (n != k)
        {
            T tmp = array[k];
            array[k] = array[n];
            array[n] = tmp;
        }
    }

    foreach (var item in array) yield return item;
}
9
ответ дан 22 November 2019 в 22:47
поделиться

Вы все, наверное, уже знаете, что интересным использованием методов расширения является вид смеси . Некоторые методы-расширения, такие как XmlSerializable, загрязняют практически каждый класс, и для большинства из них это не имеет смысла, как Thread и SqlConnection.

Часть функциональности должна быть явно смешана с классами, которые хотят ее иметь. Я предлагаю новую нотацию к этому типу, с префиксом M.

XmlSerializable XmlSerializable тогда, это:

public interface MXmlSerializable { }
public static class XmlSerializable {
  public static string ToXml(this MXmlSerializable self) {
    if (self == null) throw new ArgumentNullException();
    var serializer = new XmlSerializer(self.GetType());
    using (var writer = new StringWriter()) {
      serializer.Serialize(writer, self);
      return writer.GetStringBuilder().ToString();
    }
  }
  public static T FromXml<T>(string xml) where T : MXmlSerializable {
    var serializer = new XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(new StringReader(xml));
  }
}

Класс затем смешивает его в:

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

Если вам нравится идея, вы можете создать новое пространство имён для полезных миксов в проекте. Что вы думаете?

О, и кстати, я думаю, что большинство методов расширения должны явно тестировать на нуль.

5
ответ дан 22 November 2019 в 22:47
поделиться

Класс Random предоставляет множество функций.

Ниже приведены некоторые методы расширения, которые я время от времени использую. С ними, в дополнение к Next и NextDouble , класс Random дает вам NextBool , NextChar , NextDateTime , NextTimeSpan , NextDouble (принимает параметры minValue и maxValue ) и мои личные ] избранное: NextString . Есть и другие ( NextByte , NextShort , NextLong и т. Д.); но они в основном предназначены для полноты и редко используются. Поэтому я не включил их сюда (этот код и так достаточно длинный!).

// todo: implement additional CharType values (e.g., AsciiAny)
public enum CharType {
    AlphabeticLower,
    AlphabeticUpper,
    AlphabeticAny,
    AlphanumericLower,
    AlphanumericUpper,
    AlphanumericAny,
    Numeric
}

public static class RandomExtensions {
    // 10 digits vs. 52 alphabetic characters (upper & lower);
    // probability of being numeric: 10 / 62 = 0.1612903225806452
    private const double AlphanumericProbabilityNumericAny = 10.0 / 62.0;

    // 10 digits vs. 26 alphabetic characters (upper OR lower);
    // probability of being numeric: 10 / 36 = 0.2777777777777778
    private const double AlphanumericProbabilityNumericCased = 10.0 / 36.0;

    public static bool NextBool(this Random random, double probability) {
        return random.NextDouble() <= probability;
    }

    public static bool NextBool(this Random random) {
        return random.NextDouble() <= 0.5;
    }

    public static char NextChar(this Random random, CharType mode) {
        switch (mode) {
            case CharType.AlphabeticAny:
                return random.NextAlphabeticChar();
            case CharType.AlphabeticLower:
                return random.NextAlphabeticChar(false);
            case CharType.AlphabeticUpper:
                return random.NextAlphabeticChar(true);
            case CharType.AlphanumericAny:
                return random.NextAlphanumericChar();
            case CharType.AlphanumericLower:
                return random.NextAlphanumericChar(false);
            case CharType.AlphanumericUpper:
                return random.NextAlphanumericChar(true);
            case CharType.Numeric:
                return random.NextNumericChar();
            default:
                return random.NextAlphanumericChar();
        }
    }

    public static char NextChar(this Random random) {
        return random.NextChar(CharType.AlphanumericAny);
    }

    private static char NextAlphanumericChar(this Random random, bool uppercase) {
        bool numeric = random.NextBool(AlphanumericProbabilityNumericCased);

        if (numeric)
            return random.NextNumericChar();
        else
            return random.NextAlphabeticChar(uppercase);
    }

    private static char NextAlphanumericChar(this Random random) {
        bool numeric = random.NextBool(AlphanumericProbabilityNumericAny);

        if (numeric)
            return random.NextNumericChar();
        else
            return random.NextAlphabeticChar(random.NextBool());
    }

    private static char NextAlphabeticChar(this Random random, bool uppercase) {
        if (uppercase)
            return (char)random.Next(65, 91);
        else
            return (char)random.Next(97, 123);
    }

    private static char NextAlphabeticChar(this Random random) {
        return random.NextAlphabeticChar(random.NextBool());
    }

    private static char NextNumericChar(this Random random) {
        return (char)random.Next(48, 58);
    }

    public static DateTime NextDateTime(this Random random, DateTime minValue, DateTime maxValue) {
        return DateTime.FromOADate(
            random.NextDouble(minValue.ToOADate(), maxValue.ToOADate())
        );
    }

    public static DateTime NextDateTime(this Random random) {
        return random.NextDateTime(DateTime.MinValue, DateTime.MaxValue);
    }

    public static double NextDouble(this Random random, double minValue, double maxValue) {
        if (maxValue < minValue)
            throw new ArgumentException("Minimum value must be less than maximum value.");

        double difference = maxValue - minValue;
        if (!double.IsInfinity(difference))
            return minValue + (random.NextDouble() * difference);

        else {
            // to avoid evaluating to Double.Infinity, we split the range into two halves:
            double halfDifference = (maxValue * 0.5) - (minValue * 0.5);

            // 50/50 chance of returning a value from the first or second half of the range
            if (random.NextBool())
                return minValue + (random.NextDouble() * halfDifference);
            else
                return (minValue + halfDifference) + (random.NextDouble() * halfDifference);
        }
    }

    public static string NextString(this Random random, int numChars, CharType mode) {
        char[] chars = new char[numChars];

        for (int i = 0; i < numChars; ++i)
            chars[i] = random.NextChar(mode);

        return new string(chars);
    }

    public static string NextString(this Random random, int numChars) {
        return random.NextString(numChars, CharType.AlphanumericAny);
    }

    public static TimeSpan NextTimeSpan(this Random random, TimeSpan minValue, TimeSpan maxValue) {
        return TimeSpan.FromMilliseconds(
            random.NextDouble(minValue.TotalMilliseconds, maxValue.TotalMilliseconds)
        );
    }

    public static TimeSpan NextTimeSpan(this Random random) {
        return random.NextTimeSpan(TimeSpan.MinValue, TimeSpan.MaxValue);
    }
}
9
ответ дан 22 November 2019 в 22:47
поделиться

Я нахожу себя делающим это снова и снова, снова и снова...

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

...затем StartsWithIgnoreCase, EndsWithIgnoreCase и ContainsIgnoreCase.

6
ответ дан 22 November 2019 в 22:47
поделиться

Я только что просмотрел все 4 страницы этого документа и был довольно удивлен, что я этого не сделал » Я вижу этот способ сократить время проверки для InvokeRequired :

using System;
using System.Windows.Forms;

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

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

Использование:

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));
7
ответ дан 22 November 2019 в 22:47
поделиться

Я часто использую это с нулевыми числами. Помогает отловить деление на 0, NaN, бесконечность...

public static bool IsNullOrDefault<T>(this T? o) 
    where T : struct
{
        return o == null || o.Value.Equals(default(T));
}
4
ответ дан 22 November 2019 в 22:47
поделиться

При использовании словаря, где ключ является строкой, возвращайте существующий ключ, используя поиск без учета регистра. Мы использовали этот вариант для поиска путей к файлам.

/// <summary>
/// Gets the key using <paramref name="caseInsensitiveKey"/> from <paramref name="dictionary"/>.
/// </summary>
/// <typeparam name="T">The dictionary value.</typeparam>
/// <param name="dictionary">The dictionary.</param>
/// <param name="caseInsensitiveKey">The case insensitive key.</param>
/// <returns>
/// An existing key; or <see cref="string.Empty"/> if not found.
/// </returns>
public static string GetKeyIgnoringCase<T>(this IDictionary<string, T> dictionary, string caseInsensitiveKey)
{
    if (string.IsNullOrEmpty(caseInsensitiveKey)) return string.Empty;
    foreach (string key in dictionary.Keys)
    {
        if (key.Equals(caseInsensitiveKey, StringComparison.InvariantCultureIgnoreCase))
        {
            return key;
        }
    }
    return string.Empty;
}
6
ответ дан 22 November 2019 в 22:47
поделиться

Аналогично строкам As и Is выше, но глобально для всех объектов.

Это довольно просто, но я часто использую их, чтобы облегчить взрыв паренса с помощью бокса.

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

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

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

Я буду рад, если этот код будет использоваться на codeplex, более того, он уже используется.

10
ответ дан 22 November 2019 в 22:47
поделиться

Мое предложение:

public static bool IsNullOrEmpty(this ICollection obj)
{
  return (obj == null || obj.Count == 0);
}

Работает с коллекциями и массивами:

bool isNullOrEmpty = array.IsNullOrEmpty()

вместо

bool isNullOrEmpty = array == null || array.Length == 0;
4
ответ дан 22 November 2019 в 22:47
поделиться

GetMemberName позволяет получить строку с именем члена с безопасностью времени компиляции.

public static string GetMemberName<T, TResult>(
    this T anyObject, 
    Expression<Func<T, TResult>> expression)
{
    return ((MemberExpression)expression.Body).Member.Name;
}

Использование:

"blah".GetMemberName(x => x.Length); // returns "Length"

Он поставляется вместе со статическим методом без расширения, если вы этого не сделаете есть экземпляр:

public static string GetMemberName<T, TReturn>(
    Expression<Func<T, TReturn>> expression)
    where T : class
{
    return ((MemberExpression)expression.Body).Member.Name;
}

Но вызов, конечно, выглядит не очень красиво:

ReflectionUtility.GetMemberName((string) s => s.Length); // returns "Length"

Вы можете поместить его в Codeplex, если хотите.

2
ответ дан 22 November 2019 в 22:47
поделиться

Два маленьких (некоторые люди считают их глупыми), которые я вставляю во все свои проекты:

public static bool IsNull(this object o){
  return o == null;
}

и

public static bool IsNullOrEmpty(this string s){
  return string.IsNullOrEmpty(s);
}

Это делает мой код намного более плавным ..

if (myClassInstance.IsNull()) //... do something

if (myString.IsNullOrEmpty()) //... do something

Я думаю, что это будет действительно хорошими свойствами расширения; если мы когда-нибудь их получим.

2
ответ дан 22 November 2019 в 22:47
поделиться

Уменьшает длину строки до toLength и добавляет дополнительную строку в конец сокращенной строки, чтобы обозначить, что строка была сокращена (по умолчанию .. . )

public static string Shorten(this string str, int toLength, string cutOffReplacement = " ...")
{
    if (string.IsNullOrEmpty(str) || str.Length <= toLength)
        return str;
    else
        return str.Remove(toLength) + cutOffReplacement;
}
2
ответ дан 22 November 2019 в 22:47
поделиться

FindControl со встроенным преобразованием типов:

public static T FindControl<T>(this Control control, string id) where T : Control
{
    return (T)control.FindControl(id);
}

Ничего удивительного, но я чувствую, что это делает код более чистым.

// With extension method
container.FindControl<TextBox>("myTextBox").SelectedValue = "Hello world!";

// Without extension method
((TextBox)container.FindControl("myTextBox")).SelectedValue = "Hello world!";

При желании это можно поместить в проект codeplex

2
ответ дан 22 November 2019 в 22:47
поделиться

Этот может быть весьма полезным:

    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
    {
        if (first == null)
            throw new ArgumentNullException("first");
        if (second == null)
            throw new ArgumentNullException("second");
        if (selector == null)
            throw new ArgumentNullException("selector");

        using (var enum1 = first.GetEnumerator())
        using (var enum2 = second.GetEnumerator())
        {
            while (enum1.MoveNext() && enum2.MoveNext())
            {
                yield return selector(enum1.Current, enum2.Current);
            }
        }
    }

Он был добавлен в класс Enumerable в .NET 4.0, но его удобно иметь в 3.5.

Пример:

var names = new[] { "Joe", "Jane", "Jack", "John" };
var ages = new[] { 42, 22, 18, 33 };

var persons = names.Zip(ages, (n, a) => new { Name = n, Age = a });

foreach (var p in persons)
{
    Console.WriteLine("{0} is {1} years old", p.Name, p.Age);
}
2
ответ дан 22 November 2019 в 22:47
поделиться

Я реализовал пакет методов расширения (доступен по адресу http://foop.codeplex.com/), и некоторые из моих повседневно используемых методов:

// the most beloved extension method for me is Pipe:
<%= variable.Pipe(x => this.SomeFunction(x)).Pipe(y =>
{
    ...;
    return this.SomeOtherFunction(y);
}) %>

var d = 28.December(2009); // some extension methods for creating DateTime
DateTime justDatePart = d.JustDate();
TimeSpan justTimePart = d.JustTime();
var nextTime = d.Add(5.Hours());

using(StreamReader reader = new StreamReader("lines-of-data-file-for-example")) {
    ...
    // for reading streams line by line and usable in LINQ
    var query = from line in reader.Lines(); 
                where line.Contains(_today)
                select new { Parts = PartsOf(line), Time = _now };
}

500.Sleep();

XmlSerialize and XmlDeserialize

IsNull and IsNotNull

IfTrue, IfFalse and Iff:
true.IfTrue(() => Console.WriteLine("it is true then!");

IfNull and IfNotNull
2
ответ дан 22 November 2019 в 22:47
поделиться

Во время работы с MVC и имеющим множество , если , если я забочусь ни о том, что я только забочусь о True , либо false , и печать NULL , ИЛИ string.uppy В другом случае я придумал:

public static TResult WhenTrue<TResult>(this Boolean value, Func<TResult> expression)
{
    return value ? expression() : default(TResult);
}

public static TResult WhenTrue<TResult>(this Boolean value, TResult content)
{
    return value ? content : default(TResult);
}

public static TResult WhenFalse<TResult>(this Boolean value, Func<TResult> expression)
{
    return !value ? expression() : default(TResult);
}

public static TResult WhenFalse<TResult>(this Boolean value, TResult content)
{
    return !value ? content : default(TResult);
}

Это позволяет мне изменить <% = (Wombool)? «Распечатать y»: String.uppyty%> в <% = Coverool.whentrue («Печать Y»)%> .

Я использую его только в моих представлениях, где я смешут код и HTML, в файлах кодов, написав версию «Дольше», является более четкой IMHO.

3
ответ дан 22 November 2019 в 22:47
поделиться

String.As, который можно использовать для преобразования строкового значения as некоторого типа (предназначен для использования в основном с примитивами и типами, поддерживающими IConvertable. Отлично работает с Nullable типами и даже Enums!

public static partial class StringExtensions
{
    /// <summary>
    /// Converts the string to the specified type, using the default value configured for the type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to. The type must implement IConvertable.</typeparam>
    /// <param name="original">The original string.</param>
    /// <returns>The converted value.</returns>
    public static T As<T>(this String original)
    {
        return As(original, CultureInfo.CurrentCulture,
                  default(T));
    }

    /// <summary>
    /// Converts the string to the specified type, using the default value configured for the type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to.</typeparam>
    /// <param name="original">The original string.</param>
    /// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
    /// <returns>The converted value.</returns>
    public static T As<T>(this String original, T defaultValue)
    {
        return As(original, CultureInfo.CurrentCulture, defaultValue);
    }

    /// <summary>
    /// Converts the string to the specified type, using the default value configured for the type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to.</typeparam>
    /// <param name="original">The original string.</param>
    /// <param name="provider">Format provider used during the type conversion.</param>
    /// <returns>The converted value.</returns>
    public static T As<T>(this String original, IFormatProvider provider)
    {
        return As(original, provider, default(T));
    }

    /// <summary>
    /// Converts the string to the specified type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to.</typeparam>
    /// <param name="original">The original string.</param>
    /// <param name="provider">Format provider used during the type conversion.</param>
    /// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
    /// <returns>The converted value.</returns>
    /// <remarks>
    /// If an error occurs while converting the specified value to the requested type, the exception is caught and the default is returned. It is strongly recommended you
    /// do NOT use this method if it is important that conversion failures are not swallowed up.
    ///
    /// This method is intended to be used to convert string values to primatives, not for parsing, converting, or deserializing complex types.
    /// </remarks>
    public static T As<T>(this String original, IFormatProvider provider,
                          T defaultValue)
    {
        T result;
        Type type = typeof (T);

        if (String.IsNullOrEmpty(original)) result = defaultValue;
        else
        {
            // need to get the underlying type if T is Nullable<>.

            if (type.IsNullableType())
            {
                type = Nullable.GetUnderlyingType(type);
            }

            try
            {
                // ChangeType doesn't work properly on Enums
                result = type.IsEnum
                             ? (T) Enum.Parse(type, original, true)
                             : (T) Convert.ChangeType(original, type, provider);
            }
            catch // HACK: what can we do to minimize or avoid raising exceptions as part of normal operation? custom string parsing (regex?) for well-known types? it would be best to know if you can convert to the desired type before you attempt to do so.
            {
                result = defaultValue;
            }
        }

        return result;
    }
}

Это опирается на другое простое расширение для Type:

/// <summary>
/// Extension methods for <see cref="Type"/>.
/// </summary>
public static class TypeExtensions
{
    /// <summary>
    /// Returns whether or not the specified type is <see cref="Nullable{T}"/>.
    /// </summary>
    /// <param name="type">A <see cref="Type"/>.</param>
    /// <returns>True if the specified type is <see cref="Nullable{T}"/>; otherwise, false.</returns>
    /// <remarks>Use <see cref="Nullable.GetUnderlyingType"/> to access the underlying type.</remarks>
    public static bool IsNullableType(this Type type)
    {
        if (type == null) throw new ArgumentNullException("type");

        return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof (Nullable<>));
    }
}

Использование:

var someInt = "1".As<int>();
var someIntDefault = "bad value".As(1); // "bad value" won't convert, so the default value 1 is returned.
var someEnum = "Sunday".As<DayOfWeek>();
someEnum = "0".As<DayOfWeek>(); // returns Sunday
var someNullableEnum = "".As<DayOfWeek?>(null); // returns a null value since "" can't be converted
4
ответ дан 22 November 2019 в 22:47
поделиться

Я считаю весьма полезным следующий метод расширения:

public static T GetService<T>(this IServiceProvider provider)
{
    return (T)provider.GetService(typeof(T));
}

Он значительно упрощает использование IServiceProvider интерфейс. Сравните:

IProvideValueTarget target = (IProvideValueTarget)serviceProvider(typeof(IProvideValueTarget));

и

var target = serviceProvider.GetService<IProvideValueTarget>();
4
ответ дан 22 November 2019 в 22:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: