web-dev-qa-db-de.com

Was sind Ihre bevorzugten Erweiterungsmethoden für C #? (codeplex.com/extensionoverflow)

Lassen Sie uns eine Liste mit Antworten erstellen, in der Sie Ihre ausgezeichneten und bevorzugten Erweiterungsmethoden veröffentlichen.

Voraussetzung ist, dass der vollständige Code veröffentlicht und ein Beispiel sowie eine Erläuterung zu dessen Verwendung bereitgestellt wird.

Aufgrund des großen Interesses an diesem Thema habe ich ein Open Source-Projekt namens extensionoverflow auf Codeplex eingerichtet.

Bitte markieren Sie Ihre Antworten mit einer Bestätigung, um den Code in das Codeplex-Projekt einzufügen.

Bitte posten Sie den vollständigen Quellcode und keinen Link.

Codeplex News:

24.08.2010 Die Codeplex-Seite ist jetzt hier: http://extensionoverflow.codeplex.com/

11.11.2008 XmlSerialize/XmlDeserialize ist jetzt Implementiert und nit Tested .

11.11.2008 Es ist noch Platz für weitere Entwickler. ;-) JETZT mitmachen!

11.11.2008 Dritter Mitwirkender bei ExtensionOverflow , herzlich willkommen bei BKristensen

11.11.2008 FormatWith ist jetzt Implementiert und nit Tested .

09.11.2008 Zweiter Mitarbeiter ist ExtensionOverflow beigetreten. Willkommen zu Chakrit .

09.11.2008 Wir brauchen mehr Entwickler. ;-)

09.11.2008 ThrowIfArgumentIsNull in now Implemented und nit Tested auf Codeplex.

478
bovium

Ich benutze diese die ganze Zeit:

public static void DelimitedAppend(this StringBuilder sb, string value, string delimiter)
{
    if (sb.Length > 0)
        sb.Append(delimiter);
    sb.Append(value);
}

Dies stellt lediglich sicher, dass das Trennzeichen nicht eingefügt wird, wenn die Zeichenfolge leer ist. So erstellen Sie beispielsweise eine durch Kommas getrennte Liste von Wörtern:

var farmAnimals = new[] { new { Species = "Dog", IsTasty = false }, new { Species = "Cat", IsTasty = false }, new { Species = "Chicken", IsTasty = true }, };
var soupIngredients = new StringBuilder();
foreach (var edible in farmAnimals.Where(farmAnimal => farmAnimal.IsTasty))
    soupIngredients.DelimitedAppend(edible.Species, ", ");
1
cbp

Und einer mehr:

public enum ParseFailBehavior
{
   ReturnNull,
   ReturnDefault,
   ThrowException
}

public static T? ParseNullableEnum<T>(this string theValue, ParseFailBehavior desiredBehavior = ParseFailBehavior.ReturnNull) where T:struct
{
   T output;
   T? result = Enum.TryParse<T>(theValue, out output) 
      ? (T?)output
      : desiredBehavior == ParseFailBehavior.ReturnDefault
         ? (T?)default(T)
         : null;

   if(result == null && desiredBehavior == ParseFailBehavior.ThrowException)
      throw new ArgumentException("Parse Failed for value {0} of enum type {1}".
         FormatWith(theValue, typeof(T).Name));       
}

Diese Version erfordert .NET 4.0; In 3.5 gibt es kein TryParse und keine optionalen Parameter. Sie stecken mit Enum.Parse () fest, das Sie versuchen müssen, zu fangen. Es ist in 3.5 immer noch vollständig machbar (und viel nützlicher, da Enum.Parse () oogly und Ihre einzige andere Option ist):

public static T? ParseNummableEnum<T>(this string theValue)
{
    return theValue.ParseNullableEnum<T>(ParseFailBehavior.ReturnNull);
}

public static T? ParseNullableEnum<T>(this string theValue, 
    ParseFailBehavior desiredBehavior) where T:struct
{
    try
    {
        return (T?) Enum.Parse(typeof (T), theValue);
    }
    catch (Exception)
    {
        if(desiredBehavior == ParseFailBehavior.ThrowException) throw;
    }

    return desiredBehavior == ParseFailBehavior.ReturnDefault ? (T?)default(T) : null;
}

Verwendungszweck:

//returns null if OptionOne isn't an enum constant
var myEnum = "OptionOne".ParseNullableEnum<OptionEnum>(); 

//guarantees a return value IF the enum has a "zero" constant value (generally a good practice)
var myEnum = "OptionTwo".ParseNullableEnum<OptionEnum>(ParseFailBehavior.ReturnDefault).Value 
1
KeithS

Konvertieren Sie eine beliebige Zeichenfolge in Int32

// Calls the underlying int.TryParse method to convert a string
// representation of a number to its 32-bit signed integer equivalent.
// Returns Zero if conversion fails. 
public static int ToInt32(this string s)
{
    int retInt;
    int.TryParse(s, out retInt);
    return retInt;
}

VERWENDUNGSBEISPIEL:
string s = "999";
int i = s.ToInt32();

1
Th3Fix3r

Einige Tools zu IEnumerable: ToString (Format), ToString (Funktion) und Join (Trennzeichen).

Zum Beispiel:

var names = new[] { "Wagner", "Francine", "Arthur", "Bernardo" };

names.ToString("Name: {0}\n");
// Name: Wagner
// Name: Francine
// Name: Arthur
// Name: Bernardo

names.ToString(name => name.Length > 6 ? String.Format("{0} ", name) : String.Empty);
// Francine Bernardo

names.Join(" - ");
// Wagner - Francine - Arthur - Bernardo

Erweiterungen:

public static string ToString<T>(this IEnumerable<T> self, string format)
{
    return self.ToString(i => String.Format(format, i));
}

public static string ToString<T>(this IEnumerable<T> self, Func<T, object> function)
{
    var result = new StringBuilder();

    foreach (var item in self) result.Append(function(item));

    return result.ToString();
}

public static string Join<T>(this IEnumerable<T> self, string separator)
{
    return String.Join(separator, values: self.ToArray());
}
1
19WAS85

Das WhereIf () Methode

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

Ich habe auch Überladungen für das Indexprädikat in der Where () - Erweiterungsmethode hinzugefügt. Fügen Sie für mehr Spaß eine Variante hinzu, die ein zusätzliches 'else'-Prädikat enthält.

1
andleer

Einige handliche String-Helfer:

Verwendung:

Ich hasse unerwünschte Leerzeichen am Ende oder am Anfang von Strings und da String einen null -Wert annehmen kann, kann es schwierig sein, also benutze ich dies:

public bool IsGroup { get { return !this.GroupName.IsNullOrTrimEmpty(); } }

Hier ist eine andere Erweiterungsmethode, die ich für ein neues Validierungsframework verwende Ich teste. Sie können die Regex-Erweiterungen sehen, die beim Reinigen von ansonsten unordentlichem Regex helfen:

public static bool IsRequiredWithLengthLessThanOrEqualNoSpecial(this String str, int length)
{
    return !str.IsNullOrTrimEmpty() &&
        str.RegexMatch(
            @"^[- \r\n\\\.!:*,@$%&""?\(\)\w']{1,{0}}$".RegexReplace(@"\{0\}", length.ToString()),
            RegexOptions.Multiline) == str;
}

Quelle:

public static class StringHelpers
{
    /// <summary>
    /// Same as String.IsNullOrEmpty except that
    /// it captures the Empty state for whitespace
    /// strings by Trimming first.
    /// </summary>
    public static bool IsNullOrTrimEmpty(this String helper)
    {
        if (helper == null)
            return true;
        else
            return String.Empty == helper.Trim();
    }

    public static int TrimLength(this String helper)
    {
        return helper.Trim().Length;
    }

    /// <summary>
    /// Returns the matched string from the regex pattern. The
    /// groupName is for named group match values in the form (?<name>group).
    /// </summary>
    public static string RegexMatch(this String helper, string pattern, RegexOptions options, string groupName)
    {
        if (groupName.IsNullOrTrimEmpty())
            return Regex.Match(helper, pattern, options).Value;
        else
            return Regex.Match(helper, pattern, options).Groups[groupName].Value;
    }

    public static string RegexMatch(this String helper, string pattern)
    {
        return RegexMatch(helper, pattern, RegexOptions.None, null);
    }

    public static string RegexMatch(this String helper, string pattern, RegexOptions options)
    {
        return RegexMatch(helper, pattern, options, null);
    }

    public static string RegexMatch(this String helper, string pattern, string groupName)
    {
        return RegexMatch(helper, pattern, RegexOptions.None, groupName);
    }

    /// <summary>
    /// Returns true if there is a match from the regex pattern
    /// </summary>
    public static bool IsRegexMatch(this String helper, string pattern, RegexOptions options)
    {
        return helper.RegexMatch(pattern, options).Length > 0;
    }

    public static bool IsRegexMatch(this String helper, string pattern)
    {
        return helper.IsRegexMatch(pattern, RegexOptions.None);
    }

    /// <summary>
    /// Returns a string where matching patterns are replaced by the replacement string.
    /// </summary>
    /// <param name="pattern">The regex pattern for matching the items to be replaced</param>
    /// <param name="replacement">The string to replace matching items</param>
    /// <returns></returns>
    public static string RegexReplace(this String helper, string pattern, string replacement, RegexOptions options)
    {
        return Regex.Replace(helper, pattern, replacement, options);
    }

    public static string RegexReplace(this String helper, string pattern, string replacement)
    {
        return Regex.Replace(helper, pattern, replacement, RegexOptions.None);
    }
}

Ich mag viel Regex, deshalb halte ich das für einfacher als das Hinzufügen der using-Anweisung und des zusätzlichen Codes, um benannte Gruppen zu behandeln.

1
Matt Kocaj

Einige Erweiterungen zum Arbeiten mit Listen:

/// <summary>
/// Wrap an object in a list
/// </summary>
public static IList<T> WrapInList<T>(this T item)
{
    List<T> result = new List<T>();
    result.Add(item);
    return result;
}

benutze zB:

myList = someObject.InList();

So erstellen Sie einen IEnumerable, der Elemente aus einer oder mehreren Quellen enthält, damit IEnumerable eher wie Listen funktioniert Dies ist möglicherweise keine gute Idee für Hochleistungscode, aber nützlich für Tests:

public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, T newItem)
{
    foreach (T item in enumerable)
    {
        yield return item;
    }

    yield return newItem;
}

public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, params T[] newItems)
{
    foreach (T item in enumerable)
    {
        yield return item;
    }

    foreach (T newItem in newItems)
    {
        yield return newItem;
    }
}

verwenden Sie z.

someEnumeration = someEnumeration.Append(newItem);

Andere Variationen davon sind möglich - z.

someEnumeration = someEnumeration.Append(otherEnumeration);

Wenn Sie Elemente klonen, möchten Sie möglicherweise auch Listen davon klonen:

public static IList<T> Clone<T>(this IEnumerable<T> source) where T: ICloneable
{
    List<T> result = new List<T>();

    foreach (T item in source)
    {
        result.Add((T)item.Clone());
    }

    return result;
}

Wenn ich mit ObservableCollection<T> Arbeite, erweitere ich es im Allgemeinen mit einer AddRange-Methode. Andere Antworten hier geben Implementierungen davon.

Sie können diesen Code in das Codeplex-Projekt einfügen, wenn Sie möchten.

1
Anthony

ASP.NET HTML Encode - kurz und bündig:

public static string ToHtmlEncodedString(this string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    return HttpUtility.HtmlEncode(s);
}
1
Luke Puplett

Inline Conversions: Ich mag dieses kleine Muster. Fertiggestellt für Boolean, Double und DateTime. Entwickelt, um den Operatoren C # is und as zu folgen.

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
andleer

Entspricht der Join-Methode von Python:

/// <summary>
/// same as python 'join'
/// </summary>
/// <typeparam name="T">list type</typeparam>
/// <param name="separator">string separator </param>
/// <param name="list">list of objects to be ToString'd</param>
/// <returns>a concatenated list interleaved with separators</returns>
static public string Join<T>(this string separator, IEnumerable<T> list)
{
    var sb = new StringBuilder();
    bool first = true;

    foreach (T v in list)
    {
        if (!first)
            sb.Append(separator);
        first = false;

        if (v != null)
            sb.Append(v.ToString());
    }

    return sb.ToString();
}
1
Mark Maxham

Überschreibt einen Teil einer Zeichenfolge an einem angegebenen Index.

Ich muss mit einem System arbeiten, das erwartet, dass einige Eingabewerte eine feste Breite und feste Positionszeichenfolgen sind.

public static string Overwrite(this string s, int startIndex, string newStringValue)
{
  return s.Remove(startIndex, newStringValue.Length).Insert(startIndex, newStringValue);
}

Also kann ich tun:

string s = new String(' ',60);
s = s.Overwrite(7,"NewValue");
1
benPearce

In ASP.NET habe ich es immer satt, FindControl zu verwenden und muss dann vor dem Referenzieren prüfen, ob der Wert null ist. Also habe ich eine TryParse () -Methode zu Control hinzugefügt, die die ähnlichen im Framework für Int32 usw. widerspiegelt.

public static bool TryParse<T>(this Control control, string id, out T result) 
    where T : Control
{
    result = control.FindControl(id) as T;
    return result != null;
}

Jetzt können Sie dies in ASP.NET-Webformularseiten tun:

Label lbl;
if (Page.TryParse("Label1", out lbl))
{
    lbl.Text = "Safely set text";
}
1
Dan Diplo

Hassen Sie diese Art von Code?

CloneableClass cc1 = new CloneableClass ();
CloneableClass cc2 = null;
CloneableClass cc3 = null;

cc3 = (CloneableClass) cc1.Clone (); // this is ok
cc3 = cc2.Clone (); // this throws null ref exception
// code to handle both cases
cc3 = cc1 != null ? (CloneableClass) cc1.Clone () : null;

Es ist ein bisschen klobig, also ersetze ich es durch diese Erweiterung, die ich CloneOrNull nenne -

public static T CloneOrNull<T> (this T self) where T : class, ICloneable
{
    if (self == null) return null;
    return (T) self.Clone ();
}

Die Verwendung ist wie folgt:

CloneableClass cc1 = new CloneableClass ();
CloneableClass cc2 = null;
CloneableClass cc3 = null;

cc3 = cc1.CloneOrNull (); // clone of cc1
cc3 = cc2.CloneOrNull (); // null
// look mom, no casts!

Fühlen Sie sich bitte frei, dieses überall zu verwenden!

1
PhilChuang

Ich verwende immer das Format, das eine neue Zeile mit StringBuilder haben soll, so dass die sehr einfache Erweiterung unten ein paar Codezeilen spart:

public static class Extensions
{
    public static void AppendLine(this StringBuilder builder,string format, params object[] args)
    {
        builder.AppendLine(string.Format(format, args));
    }
}

Die Alternative ist AppendFormat in StringBuilder mit einem \n oder Environment.NewLine.

1
Chris S

Ein generischer Versuch:

class Program
{
    static void Main(string[] args)
    {
        var z = 0;
        var a = 0.AsDefaultFor(() => 1 / z);
        Console.WriteLine(a);
        Console.ReadLine();
    }
}

public static class TryExtensions
{
    public static T AsDefaultFor<T>(this T @this, Func<T> operation)
    {
        try
        {
            return operation();
        }
        catch
        {
            return @this;
        }
    }
}

Stellen Sie es in das CodePlex-Projekt, wenn Sie möchten.

Ich habe noch keine Antwort mit diesem gesehen ...

public static string[] Split(this string value, string regexPattern)
{
    return value.Split(regexPattern, RegexOptions.None);
}

public static string[] Split(this string value, string regexPattern, 
    RegexOptions options)
{
    return Regex.Split(value, regexPattern, options);
}

Verwendungszweck:

var obj = "test1,test2,test3";
string[] arrays = obj.Split(",");
1
jaekie

Manchmal muss eine Instanz der Klasse vorhanden sein, egal ob gültig, aber nicht null

public static T Safe<T>(this T obj) where T : new()
{
    if (obj == null)
    {
        obj = new T();
    }

    return obj;
}

verwendung wird wie folgt sein:

MyClass myClass = Provider.GetSomeResult();
string temp = myClass.Safe().SomeValue;

anstatt von:

MyClass myClass = Provider.GetSomeResult();
string temp = "some default value";
if (myClass != null)
{
        temp = myClass.SomeValue;
}

es tut mir leid, wenn es eine Duplizität ist, aber ich finde es nicht.

1
sasjaq

Ein Parsing-Muster, das out -Parameter vermeidet:

public static bool TryParseInt32(this string input, Action<int> action)
{
    int result;
    if (Int32.TryParse(input, out result))
    {
        action(result);
        return true;
    }
    return false;
}

Verwendungszweck:

if (!textBox.Text.TryParseInt32(number => label.Text = SomeMathFunction(number)))
    label.Text = "Please enter a valid integer";

Dies kann auf Wunsch in das Codeplex-Projekt eingefügt werden

1
Greg

Mehrmals wollte ich so etwas wie Groovys "Sichere Navigation".

Von http://groovy.codehaus.org/Statements :

Wenn Sie ein komplexes Objektdiagramm durchlaufen und keine NullPointerExceptions ausgelöst haben möchten, können Sie das? Verwenden. Betreiber statt. um Ihre Navigation durchzuführen.

def foo = null def bar = foo? .something? .myMethod () assert bar == null

Halten Sie es für eine gute Idee, eine Erweiterungsmethode hinzuzufügen? So etwas wie:

obj.SafelyNavigate(x => x.SomeProperty.MaybeAMethod().AnotherProperty);

Ich denke, es wäre schön, wenn es auch Ärger bringen könnte.

Wenn Sie denken, dass es eine gute Idee ist:

  • Was denkst du, sollte es für Werttypen passieren? Standard zurückgeben? werfen ?, deaktivieren Sie es durch generische Einschränkung ?.
  • NullReferenceException zu schlucken, um es zu implementieren, wäre zu riskant. Was schlagen Sie vor? Den Ausdrucksbaum zu durchlaufen, der jeden Aufruf oder jeden Mitgliederzugriff ausführt, erscheint schwierig und übertrieben (wenn überhaupt möglich), nicht wahr?.

Vielleicht ist es nur eine schlechte Idee: D, aber ich sehe es als etwas, das nützlich sein kann, wenn es richtig gemacht wird. Wenn es nichts Vergleichbares gibt und Sie der Meinung sind, dass es etwas wert ist, kann ich es ausprobieren und die Antwort anschließend bearbeiten.

1
Fredy Treboux

Whitespace-Normalisierung ist besonders bei Benutzereingaben nützlich:

namespace Extensions.String
{
    using System.Text.RegularExpressions;

    public static class Extensions
    {
        /// <summary>
        /// Normalizes whitespace in a string.
        /// Leading/Trailing whitespace is eliminated and
        /// all sequences of internal whitespace are reduced to
        /// a single SP (ASCII 0x20) character.
        /// </summary>
        /// <param name="s">The string whose whitespace is to be normalized</param>
        /// <returns>a normalized string</returns>
        public static string NormalizeWS( this string @this )
        {
            string src        = @this ?? "" ;
            string normalized = rxWS.Replace( src , m =>{
                  bool isLeadingTrailingWS = ( m.Index == 0 || m.Index+m.Length == src.Length ? true : false ) ;
                  string p                 = ( isLeadingTrailingWS ? "" : " " ) ;
                  return p ;
                }) ;

            return normalized ;

        }
        private static Regex rxWS = new Regex( @"\s+" ) ;
    }
}
1
Nicholas Carey

Verwenden Sie Reflection, um die TryParse-Methode zu finden und sie bei einem Zeichenfolgenziel aufzurufen. Der optionale Parameter gibt an, was zurückgegeben werden soll, wenn die Konvertierung fehlschlägt. Ich finde diese Methode die meiste Zeit recht nützlich. Gut bewusst von der Convert.ChangeType Option, aber ich finde das nützlicher, was mit dem Standardergebnis praktisch ist und was nicht. Beachten Sie, dass die gefundenen Methoden in einem Wörterbuch aufbewahrt werden, obwohl ich vermute, dass das Boxen dies letztendlich etwas verlangsamt.

Diese Methode ist meine Lieblingsmethode, da sie zu Recht viele Sprachfunktionen verwendet.

private static readonly Dictionary<Type, MethodInfo> Parsers = new Dictionary<Type, MethodInfo>();

public static T Parse<T>(this string value, T defaultValue = default(T))
{
    if (string.IsNullOrEmpty(value)) return defaultValue;

    if (!Parsers.ContainsKey(typeof(T)))
        Parsers[typeof (T)] = typeof (T).GetMethods(BindingFlags.Public | BindingFlags.Static)
            .Where(mi => mi.Name == "TryParse")
            .Single(mi =>
                        {
                            var parameters = mi.GetParameters();
                            if (parameters.Length != 2) return false;
                            return parameters[0].ParameterType == typeof (string) &&
                                   parameters[1].ParameterType == typeof (T).MakeByRefType();
                        });

    var @params = new object[] {value, default(T)};
    return (bool) Parsers[typeof (T)].Invoke(null, @params) ?
        (T) @params[1] : defaultValue;
}

Verwendungszweck:

var hundredTwentyThree = "123".Parse(0);
var badnumber = "test".Parse(-1);
var date = "01/01/01".Parse<DateTime>();
1
Gleno

Ein paar nützliche Erweiterungen, wenn Sie mit Geschäftsjahren arbeiten

/// <summary>
/// Returns the fiscal year for the passed in date
/// </summary>
/// <param name="value">the date</param>
/// <returns>the fiscal year</returns>
public static int FiscalYear(this DateTime value)
{
  int ret = value.Year;
  if (value.Month >= 7) ret++;
  return ret;
}

/// <summary>
/// Returns the fiscal year for the passed in date
/// </summary>
/// <param name="value">the date</param>
/// <returns>the fiscal year</returns>
public static string FiscalYearString(this DateTime value)
{
  int fy = FiscalYear(value);
  return "{0}/{1}".Format(fy - 1, fy);
}
1
John

Dies ist eine Erweiterungsmethode für die ASP.Net MVC-Hilfsmethode für Aktionslinks, mit der mithilfe der Berechtigungsattribute des Controllers entschieden werden kann, ob der Link für die Ansicht des aktuellen Benutzers aktiviert, deaktiviert oder ausgeblendet werden soll. Ich erspare Ihnen, dass Sie Ihre eingeschränkten Aktionen nicht in "if" -Klauseln einschließen müssen, in denen in allen Ansichten geprüft wird, ob ein Benutzer Mitglied ist. Vielen Dank an Maarten Balliauw für die Idee und die Code-Bits, die mir den Weg gezeigt haben :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using System.Web.Routing;
using System.Web.Mvc;
using System.Collections;
using System.Reflection;
namespace System.Web.Mvc.Html
{
    public static class HtmlHelperExtensions
    {

        /// <summary>
        /// Shows or hides an action link based on the user's membership status
        /// and the controller's authorize attributes
        /// </summary>
        /// <param name="linkText">The link text.</param>
        /// <param name="action">The controller action name.</param>
        /// <param name="controller">The controller name.</param>
        /// <returns></returns>
        public static string SecurityTrimmedActionLink(
            this HtmlHelper htmlHelper,
            string linkText,
            string action,
            string controller)
        {
            return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, false, null);
        }

        /// <summary>
        /// Enables, disables or hides an action link based on the user's membership status
        /// and the controller's authorize attributes
        /// </summary>
        /// <param name="linkText">The link text.</param>
        /// <param name="action">The action name.</param>
        /// <param name="controller">The controller name.</param>
        /// <param name="showDisabled">if set to <c>true</c> [show link as disabled - 
        /// using a span tag instead of an anchor tag ].</param>
        /// <param name="disabledAttributeText">Use this to add attributes to the disabled
        /// span tag.</param>
        /// <returns></returns>
        public static string SecurityTrimmedActionLink(
            this HtmlHelper htmlHelper, 
            string linkText, 
            string action, 
            string controller, 
            bool showDisabled, 
            string disabledAttributeText)
        {
            if (IsAccessibleToUser(action, controller, HttpContext.Current ))
            {
                return htmlHelper.ActionLink(linkText, action, controller);
            }
            else
            {
                return showDisabled ? 
                    String.Format(
                        "<span{1}>{0}</span>", 
                        linkText, 
                        disabledAttributeText==null?"":" "+disabledAttributeText
                        ) : "";
            }
        }

        private static IController GetControllerInstance(string controllerName)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Type controllerType = GetControllerType(controllerName);
            return (IController)Activator.CreateInstance(controllerType);
        }

        private static ArrayList GetControllerAttributes(string controllerName, HttpContext context)
        {
            if (context.Cache[controllerName + "_ControllerAttributes"] == null)
            {
                var controller = GetControllerInstance(controllerName);

                context.Cache.Add(
                    controllerName + "_ControllerAttributes",
                    new ArrayList(controller.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true)),
                    null,
                    Caching.Cache.NoAbsoluteExpiration,
                    Caching.Cache.NoSlidingExpiration,
                    Caching.CacheItemPriority.Default,
                    null);

            }
            return (ArrayList)context.Cache[controllerName + "_ControllerAttributes"];

        }

        private static ArrayList GetMethodAttributes(string controllerName, string actionName, HttpContext context)
        {
            if (context.Cache[controllerName + "_" + actionName + "_ActionAttributes"] == null)
            {
                ArrayList actionAttrs = new ArrayList();
                var controller = GetControllerInstance(controllerName);
                MethodInfo[] methods = controller.GetType().GetMethods();

                foreach (MethodInfo method in methods)
                {
                    object[] attributes = method.GetCustomAttributes(typeof(ActionNameAttribute), true);

                    if ((attributes.Length == 0 && method.Name == actionName)
                        ||
                        (attributes.Length > 0 && ((ActionNameAttribute)attributes[0]).Name == actionName))
                    {
                        actionAttrs.AddRange(method.GetCustomAttributes(typeof(AuthorizeAttribute), true));
                    }
                }

                context.Cache.Add(
                    controllerName + "_" + actionName + "_ActionAttributes",
                    actionAttrs,
                    null,
                    Caching.Cache.NoAbsoluteExpiration,
                    Caching.Cache.NoSlidingExpiration,
                    Caching.CacheItemPriority.Default,
                    null);

            }

            return (ArrayList)context.Cache[controllerName + "_" + actionName+ "_ActionAttributes"]; 
        }

        public static bool IsAccessibleToUser(string actionToAuthorize, string controllerToAuthorize, HttpContext context)
        {
            IPrincipal principal = context.User;

            //cache the attribute list for both controller class and it's methods

            ArrayList controllerAttributes = GetControllerAttributes(controllerToAuthorize, context);

            ArrayList actionAttributes = GetMethodAttributes(controllerToAuthorize, actionToAuthorize, context);                        

            if (controllerAttributes.Count == 0 && actionAttributes.Count == 0)
                return true;

            string roles = "";
            string users = "";
            if (controllerAttributes.Count > 0)
            {
                AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute;
                roles += attribute.Roles;
                users += attribute.Users;
            }
            if (actionAttributes.Count > 0)
            {
                AuthorizeAttribute attribute = actionAttributes[0] as AuthorizeAttribute;
                roles += attribute.Roles;
                users += attribute.Users;
            }

            if (string.IsNullOrEmpty(roles) && string.IsNullOrEmpty(users) && principal.Identity.IsAuthenticated)
                return true;

            string[] roleArray = roles.Split(',');
            string[] usersArray = users.Split(',');
            foreach (string role in roleArray)
            {
                if (role == "*" || principal.IsInRole(role))
                    return true;
            }
            foreach (string user in usersArray)
            {
                if (user == "*" && (principal.Identity.Name == user))
                    return true;
            }
            return false;
        }

        private static Type GetControllerType(string controllerName)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            foreach (Type type in Assembly.GetTypes())
            {
                if (
                    type.BaseType!=null 
                    && type.BaseType.Name == "Controller" 
                    && (type.Name.ToUpper() == (controllerName.ToUpper() + "Controller".ToUpper())))
                {
                    return type;
                }
            }
            return null;
        }

    }
}
1
Robert Dean

Für ASP.NET verwende ich diese Erweiterungen für HttpSessionState, um Objekte in die Sitzung zu laden. Sie können Sitzungsobjekte auf saubere Weise laden und sie erstellen und initialisieren, wenn sie nicht vorhanden sind. Ich benutze die beiden Erweiterungsmethoden wie folgt:

private bool CreateMode;
private MyClass SomeClass;

protected override void OnInit (EventArgs e)
{
    CreateMode = Session.GetSessionValue<bool> ("someKey1", () => true);
    SomeClass = Session.GetSessionClass<MyClass> ("someKey2", () => new MyClass () 
    { 
       MyProperty = 123 
    });
}

Hier sind die Erweiterungsklassen:

public static class SessionExtensions    
{
    public delegate object UponCreate ();
    public static T GetSessionClass<T> (this HttpSessionState session, 
       string key, UponCreate uponCreate) where T : class
    {
        if (null == session[key])
        {
            var item = uponCreate () as T;
            session[key] = item;
            return item;
        }
        return session[key] as T;
    }
    public static T GetSessionValue<T> (this HttpSessionState session, 
       string key, UponCreate uponCreate) where T : struct
    {
        if (null == session[key])
        {
            var item = uponCreate();
            session[key] = item;
            return (T)item;
        }
        return (T)session[key];
    }
}
</ code>
1
moomi

bei der Serialisierung und Konfiguration ist es besser, long als DateTime zu verwenden.

    public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0);

    public static long ToUnixTimestamp(this DateTime dateTime)
    {
        return (long) (dateTime - Epoch).TotalSeconds;
    }

    public static long ToUnixUltraTimestamp(this DateTime dateTime)
    {
        return (long) (dateTime - Epoch).TotalMilliseconds;
    }

und rückwärts

    public static DateTime ToDateTime(this long unixDateTime)
    {
        return Epoch.AddSeconds(unixDateTime);
    }

    public static DateTime ToDateTimeUltra(this long unixUltraDateTime)
    {
        return Epoch.AddMilliseconds(unixUltraDateTime);
    }
0
sasjaq

Und hier ist die Control-Invoke-Erweiterung, die ich regelmäßig benutze.

public static class InvokeExtensions
{
    public static void InvokeHandler(this Control control, MethodInvoker del) // Sync. control-invoke extension.
    {
        if (control.InvokeRequired)
        {
            control.Invoke(del);
            return; 
        }
        del(); // run the actual code.
    }

    public static void AsyncInvokeHandler(this Control control, MethodInvoker del) // Async. control-invoke extension.
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(del);
            return; 
        }
        del(); // run the actual code.
    }
}

stichprobe;

this.TreeView.AsyncInvokeHandler(() =>
        {
            this.Text = 'xyz'
        });

das erlaubt Cross-Thread-GUI-Updates.

0
HuseyinUslu
  • Zum Hinzufügen mehrerer Elemente zu einer Sammlung ohne AddRange, z. B. collection.Add(item1, item2, itemN);

    static void Add<T>(this ICollection<T> coll, params T[] items)
     { foreach (var item in items) coll.Add(item);
     }
    
  • Das Folgende ist wie string.Format(), jedoch mit einer benutzerdefinierten Zeichenfolgendarstellung von Argumenten, z. B. "{0} {1} {2}".Format<Custom>(c=>c.Name,"string",new object(),new Custom()) ergibt "string {System.Object} Custom1Name"

    static string Format<T>(  this string format
                            , Func<T,object> select
                            , params object[] args)
     { for(int i=0; i < args.Length; ++i)
        { var x = args[i] as T;
          if (x != null) args[i] = select(x);
        }
       return string.Format(format, args);
     }
    
0
Mark Cidade
public static class DictionaryExtensions
{
    public static Nullable<TValue> GetValueOrNull<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
        where TValue : struct
    {
        TValue result;
        if (dictionary.TryGetValue(key, out result))
            return result;
        else
            return null;
    }
}

Geben Sie zur Verwendung einfach meinen Namen (Janko Röbisch) im Code an.

0
Janko R

Wir haben ein Bereitstellungstool für die Bereitstellung zwischen Umgebungen. Da die Dateien als geändert, aber nicht wirklich anders markiert werden konnten, kam ich auf Folgendes:

/// <summary>
/// Compares the files to see if they are different. 
/// First checks file size
/// Then modified if the file is larger than the specified size
/// Then compares the bytes
/// </summary>
/// <param name="file1">The source file</param>
/// <param name="file2">The destination file</param>
/// <param name="mb">Skip the smart check if the file is larger than this many megabytes. Default is 10.</param>
/// <returns></returns>
public static bool IsDifferentThan(this FileInfo file1, FileInfo file2, int mb = 10)
{
  var ret = false;

  // different size is a different file
  if(file1.Length != file2.Length) return true;

  // if the file times are different and the file is bigger than 10mb flag it for updating
  if(file1.LastWriteTimeUtc > file2.LastWriteTimeUtc && file1.Length > ((mb*1024)*1024)) return true;

  var f1 = File.ReadAllBytes(file1.FullName);
  var f2 = File.ReadAllBytes(file2.FullName);

  // loop through backwards because if they are different
  // it is more likely that the last few bytes will be different
  // than the first few
  for(var i = file1.Length - 1; i > 0; i--)
  {
    if(f1[i] != f2[i])
    {
      ret = true;
      break;
    }
  }

  return ret;
}
0
John

Dieser ist nicht vollständig gebacken, da wir ihn uns heute Morgen gerade ausgedacht haben. Es wird eine vollständige Klassendefinition für einen Typ generiert. Nützlich für Situationen, in denen Sie eine große Klasse haben und eine Teilmenge oder vollständige Definition erstellen möchten, aber keinen Zugriff darauf haben. Zum Beispiel, um das Objekt in einer Datenbank usw. zu speichern.

public static class TypeExtensions
{
    public static string GenerateClassDefinition(this Type type)
    {
        var properties = type.GetFields();
        var sb = new StringBuilder();
        var classtext = @"private class $name
        {
         $props}";

        foreach (var p in GetTypeInfo(type))
        {
            sb.AppendFormat("  public {0} {1} ", p.Item2, p.Item1).AppendLine(" { get; set; }");
        }

        return classtext.Replace("$name", type.Name).Replace("$props", sb.ToString());
    }

    #region Private Methods
    private static List<Tuple<string, string>> GetTypeInfo(Type type)
    {
        var ret = new List<Tuple<string, string>>();
        var fields = type.GetFields();
        var props = type.GetProperties();

        foreach(var p in props) ret.Add(new Tuple<string, string>(p.Name, TranslateType(p.PropertyType)));    
        foreach(var f in fields) ret.Add(new Tuple<string, string>(f.Name, TranslateType(f.FieldType)));

        return ret;
    }


    private static string TranslateType(Type input)
    {
        string ret;

        if (Nullable.GetUnderlyingType(input) != null)
        {
            ret = string.Format("{0}?", TranslateType(Nullable.GetUnderlyingType(input)));
        }
        else
        {
            switch (input.Name)
            {
                case "Int32": ret = "int"; break;
                case "Int64": ret = "long"; break;
                case "IntPtr": ret = "long"; break;
                case "Boolean": ret = "bool"; break;
                case "String":
                case "Char":
                case "Decimal":
                    ret = input.Name.ToLower(); break;
                default: ret = input.Name; break;
            }
        }

        return ret;
    }
    #endregion
}

Anwendungsbeispiel:

Process.GetProcesses().First().GetType().GenerateClassDefinition();

Wird mit linqpad noch praktischer:

Process.GetProcesses().First().GetType().GenerateClassDefinition().Dump();
0
John

Ein weiteres Mal, um UriBuilder im Umgang mit Abfrageparametern benutzerfreundlicher zu gestalten.

    /// <summary>
    /// Adds the specified query parameter to the URI builder.
    /// </summary>
    /// <param name="builder">The builder.</param>
    /// <param name="parameterName">Name of the parameter.</param>
    /// <param name="value">The URI escaped value.</param>
    /// <returns>The final full query string.</returns>
    public static string AddQueryParam(this UriBuilder builder, string parameterName, string value)
    {
        if (parameterName == null)
            throw new ArgumentNullException("parameterName");

        if (parameterName.Length == 0)
            throw new ArgumentException("The parameter name is empty.");

        if (value == null)
            throw new ArgumentNullException("value");

        if (value.Length == 0)
            throw new ArgumentException("The value is empty.");

        if (builder.Query.Length == 0)
        {
            builder.Query = String.Concat(parameterName, "=", value);
        }
        else if
            (builder.Query.Contains(String.Concat("&", parameterName, "="))
            || builder.Query.Contains(String.Concat("?", parameterName, "=")))
        {
            throw new InvalidOperationException(String.Format("The parameter {0} already exists.", parameterName));
        }
        else
        {
            builder.Query = String.Concat(builder.Query.Substring(1), "&", parameterName, "=", value);
        }

        return builder.Query;
    }
0
Luke Puplett

Im Abschnitt "Letzte Suchanfragen" auf meiner Blog-Statistikseite hatte ich alle Duplikate entfernt, brauchte jedoch eine Möglichkeit, um fast doppelte Zeilen zu entfernen. Ich würde Unmengen ähnlicher, aber nicht ganz gleicher Google-Abfragen erhalten.

Ich habe einen anonymen Typ anstelle eines Wörterbuchs verwendet, wollte aber eine Liste dieses anonymen Typs erstellen. Sie können das nicht tun, aber Sie können ein List<dynamic> In .NET 4.0 erstellen :)

Am meisten gefällt es mir, weil ich effektiv eine List<AnonymousType#1>() bekomme.

/// <summary>Remove extraneous entries for common Word permutations</summary>
/// <param name="input">Incoming series of words to be filtered</param>
/// <param name="MaxIgnoreLength">Words this long or shorter will not count as duplicates</param>
/// <param name="words2">Instance list from BuildInstanceList()</param>
/// <returns>Filtered list of lines from input, based on filter info in words2</returns>
private static List<string> FilterNearDuplicates(List<string> input, int MaxIgnoreLength, List<dynamic> words2)
{
    List<string> output = new List<string>();
    foreach (string line in input)
    {
        int Dupes = 0;
        foreach (string Word in line.Split(new char[] { ' ', ',', ';', '\\', '/', ':', '\"', '\r', '\n', '.' })
            .Where(p => p.Length > MaxIgnoreLength)
            .Distinct())
        {
            int Instances = 0;
            foreach (dynamic dyn in words2)
            if (Word == dyn.Word)
            {
                Instances = dyn.Instances;
                if (Instances > 1)
                    Dupes++;
                break;
            }
        }
        if (Dupes == 0)
            output.Add(line);
    }
    return output;
}
/// <summary>Builds a list of words and how many times they occur in the overall list</summary>
/// <param name="input">Incoming series of words to be counted</param>
/// <returns></returns>
private static List<dynamic> BuildInstanceList(List<string> input)
{
    List<dynamic> words2 = new List<object>();
    foreach (string line in input)
    foreach (string Word in line.Split(new char[] { ' ', ',', ';', '\\', '/', ':', '\"', '\r', '\n', '.' }))
    {
        if (string.IsNullOrEmpty(Word))
            continue;
        else if (ExistsInList(Word, words2))
            for (int i = words2.Count - 1; i >= 0; i--)
            {
                if (words2[i].Word == Word)
                    words2[i] = new { Word = words2[i].Word, Instances = words2[i].Instances + 1 };
            }
        else
            words2.Add(new { Word = Word, Instances = 1 });
    }

    return words2;
}
/// <summary>Determines whether a dynamic Word object exists in a List of this dynamic type.</summary>
/// <param name="Word">Word to look for</param>
/// <param name="words">Word dynamics to search through</param>
/// <returns>Indicator of whether the Word exists in the list of words</returns>
private static bool ExistsInList(string Word, List<dynamic> words)
{
    foreach (dynamic dyn in words)
        if (dyn.Word == Word)
            return true;
    return false;
}
0
tsilb
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MinGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
    if(items.IsEmpty()) {
        return (new List<T> { new T() }).Min(expression);
    }
    return items.Min(expression);
}

// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MaxGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
    if(items.IsEmpty()) {
        return (new List<T> { new T() }).Max(expression);
    }
    return items.Max(expression);
}

Ich bin nicht sicher, ob es einen besseren Weg gibt, aber diese Erweiterung ist sehr hilfreich, wenn ich die Standardwerte von Feldern in meinem Objekt steuern möchte.
Wenn ich beispielsweise den Wert einer DateTime steuern und gemäß meiner Geschäftslogik festlegen möchte, kann ich dies im Standardkonstruktor tun. Ansonsten ist es DateTime.MinDate.

0

Ich habe eine Erweiterungsmethode erstellt, um ein Element in einer Dropdown-Liste in ASP.NET auszuwählen.

Unten ist der Code

 public static class Utilities
{
    public enum DropDownListSelectionType
    {
        ByValue,
        ByText
    }

    public static void SelectItem(this  System.Web.UI.WebControls.DropDownList drp, string selectedValue, DropDownListSelectionType type)
    {
        drp.ClearSelection();
        System.Web.UI.WebControls.ListItem li;
        if (type == DropDownListSelectionType.ByValue)
            li = drp.Items.FindByValue(selectedValue.Trim());
        else
            li = drp.Items.FindByText(selectedValue.Trim());
        if (li != null)
            li.Selected = true;
    }}

Diese Methode kann durch die folgenden Codezeilen aufgerufen werden, um entweder nach Text auszuwählen

DropDownList1.SelectItem("ABCD", Utilities.DropDownListSelectionType.ByText);

oder nach Wert auswählen

DropDownList1.SelectItem("11", Utilities.DropDownListSelectionType.ByValue);

Der obige Code wählt nichts aus, wenn er den übergebenen Text/Wert nicht findet.

0
Chris Job
// This file contains extension methods for generic List<> class to operate on sorted lists.
// Duplicate values are OK.
// O(ln(n)) is still much faster then the O(n) of LINQ's searches/filters.
static partial class SortedList
{
    // Return the index of the first element with the key greater then provided.
    // If there's no such element within the provided range, it returns iAfterLast.
    public static int sortedFirstGreaterIndex<tElt, tKey>( this IList<tElt> list, Func<tElt, tKey, int> comparer, tKey key, int iFirst, int iAfterLast )
    {
        if( iFirst < 0 || iAfterLast < 0 || iFirst > list.Count || iAfterLast > list.Count )
            throw new IndexOutOfRangeException();
        if( iFirst > iAfterLast )
            throw new ArgumentException();
        if( iFirst == iAfterLast )
            return iAfterLast;

        int low = iFirst, high = iAfterLast;
        // The code below is inspired by the following article:
        // http://en.wikipedia.org/wiki/Binary_search#Single_comparison_per_iteration
        while( low < high )
        {
            int mid = ( high + low ) / 2;
            // 'mid' might be 'iFirst' in case 'iFirst+1 == iAfterLast'.
            // 'mid' will never be 'iAfterLast'.
            if( comparer( list[ mid ], key ) <= 0 ) // "<=" since we gonna find the first "greater" element
                low = mid + 1;
            else
                high = mid;
        }
        return low;
    }

    // Return the index of the first element with the key greater then the provided key.
    // If there's no such element, returns list.Count.
    public static int sortedFirstGreaterIndex<tElt, tKey>( this IList<tElt> list, Func<tElt, tKey, int> comparer, tKey key )
    {
        return list.sortedFirstGreaterIndex( comparer, key, 0, list.Count );
    }

    // Add an element to the sorted array.
    // This could be an expensive operation if frequently adding elements that sort firstly.
    // This is cheap operation when adding elements that sort near the tail of the list.
    public static int sortedAdd<tElt>( this List<tElt> list, Func<tElt, tElt, int> comparer, tElt elt )
    {
        if( list.Count == 0 || comparer( list[ list.Count - 1 ], elt ) <= 0 )
        {
            // either the list is empty, or the item is greater then all elements already in the collection.
            list.Add( elt );
            return list.Count - 1;
        }
        int ind = list.sortedFirstGreaterIndex( comparer, elt );
        list.Insert( ind, elt );
        return ind;
    }

    // Find first exactly equal element, return -1 if not found.
    public static int sortedFindFirstIndex<tElt, tKey>( this List<tElt> list, Func<tElt, tKey, int> comparer, tKey elt )
    {
        int low = 0, high = list.Count - 1;

        while( low < high )
        {
            int mid = ( high + low ) / 2;
            if( comparer( list[ mid ], elt ) < 0 )
                low = mid + 1;
            else
                high = mid; // this includes the case when we've found an element exactly matching the key
        }
        if( high >= 0 && 0 == comparer( list[ high ], elt ) )
            return high;
        return -1;
    }

    // Return the IEnumerable that returns array elements in the reverse order.
    public static IEnumerable<tElt> sortedReverse<tElt>( this List<tElt> list )
    {
        for( int i=list.Count - 1; i >= 0; i-- )
            yield return list[ i ];
    }
}
0
Soonts
// Values ordered true/false
// True/false values separated by a capital letter
// Only two values allowed
// ---------------------------
// Limited, but could be useful
public enum BooleanFormat
{
    OneZero,
    YN,
    YesNo,
    TF,
    TrueFalse,
    PassFail,
    YepNope
}

public static class BooleanExtension
{
    /// <summary>
    /// Converts the boolean value of this instance to the specified string value. 
    /// </summary>
    private static string ToString(this bool value, string passValue, string failValue)
    {
        return value ? passValue : failValue;
    }

    /// <summary>
    /// Converts the boolean value of this instance to a string. 
    /// </summary>
    /// <param name="booleanFormat">A BooleanFormat value. 
    /// Example: BooleanFormat.PassFail would return "Pass" if true and "Fail" if false.</param>
    /// <returns>Boolean formatted string</returns>
    public static string ToString(this bool value, BooleanFormat booleanFormat)
    {
        string booleanFormatString = Enum.GetName(booleanFormat.GetType(), booleanFormat);
        return ParseBooleanString(value, booleanFormatString);      
    }

    // Parses boolean format strings, not optimized
    private static string ParseBooleanString(bool value, string booleanFormatString)
    {
        StringBuilder trueString = new StringBuilder();
        StringBuilder falseString = new StringBuilder();

        int charCount = booleanFormatString.Length;

        bool isTrueString = true;

        for (int i = 0; i != charCount; i++)
        {
            if (char.IsUpper(booleanFormatString[i]) && i != 0)
                isTrueString = false;

            if (isTrueString)
                trueString.Append(booleanFormatString[i]);
            else
                falseString.Append(booleanFormatString[i]);
        }

        return (value == true ? trueString.ToString() : falseString.ToString());
    }
0
Chris

Wenn Sie Persisch sprechen und Benutzern die Nummern in Persisch anzeigen müssen:

static public string ToFaString         (this string value)
        {
            // 1728 , 1584
            string result = "";
            if (value != null)
            {
                char[] resChar = value.ToCharArray();
                for (int i = 0; i < resChar.Length; i++)
                {
                    if (resChar[i] >= '0' && resChar[i] <= '9')
                        result += (char)(resChar[i] + 1728);
                    else
                        result += resChar[i];
                }
            }
            return result;
        }
0
NeverFade

Einige DataSet/DataRow-Erweiterungen vereinfachen die Arbeit mit Datenbankergebnissen

Verwenden Sie einfach .Field ("fieldname") in der DataRow und es wird es umgewandelt, wenn dies möglich ist. Optional kann ein Standardwert angegeben werden.

Außerdem .HasRows () im DataSet, sodass Sie nicht prüfen müssen, ob eine Tabelle und Zeilen vorhanden sind.

Beispiel:

using (DataSet ds = yourcall()) 
{
  if (ds.HasRows())
  {
     foreach (DataRow dr in ds.Tables[0].Rows)
     {
        int id = dr.Field<int>("ID");
        string name = dr.Field<string>("Name");
        string Action = dr.Field<string>("Action", "N/A");
     }
  }
}

Code:

using System;
using System.Data;

public static class DataSetExtensions
{
    public static T Field<T>(this DataRow row, string columnName, T defaultValue)
    {
        try
        {
            return row.Field<T>(columnName);
        }
        catch
        {
            return defaultValue;
        }
    }

    public static T Field<T>(this DataRow row, string columnName)
    {
        if (row[columnName] == null)
            throw new NullReferenceException(columnName + " does not exist in DataRow");

        string value = row[columnName].ToString();

        if (typeof(T) == "".GetType())
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        else if (typeof(T) == 0.GetType())
        {
            return (T)Convert.ChangeType(int.Parse(value), typeof(T));
        }
        else if (typeof(T) == false.GetType())
        {
            return (T)Convert.ChangeType(bool.Parse(value), typeof(T));
        }
        else if (typeof(T) == DateTime.Now.GetType())
        {
            return (T)Convert.ChangeType(DateTime.Parse(value), typeof(T));
        }
        else if (typeof(T) == new byte().GetType())
        {
            return (T)Convert.ChangeType(byte.Parse(value), typeof(T));
        }
        else if (typeof(T) == new float().GetType())
        {
            return (T)Convert.ChangeType(float.Parse(value), typeof(T));
        }
        else
        {
            throw new ArgumentException(string.Format("Cannot cast '{0}' to '{1}'.", value, typeof(T).ToString()));
        }
    }

    public static bool HasRows(this DataSet dataSet) 
    {
        return (dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0);
    }
}
0
CaffGeek

Wenn Sie überprüfen müssen, ob Ihre Zeichenfolge für Is All char 0 ist:

 static public bool   IsAllZero            (this string input)
        {
            if(string.IsNullOrEmpty(input))
                return true;
            foreach (char ch in input)
            {
                if(ch != '0')
                    return false;
            }
            return true;
        }
0
NeverFade

Wie wäre es mit ...

public static bool IsWinXPOrHigher(this OperatingSystem OS)
{
  return (OS.Platform == PlatformID.Win32NT)
    && ((OS.Version.Major > 5) || ((OS.Version.Major == 5) && (OS.Version.Minor >= 1)));
}

public static bool IsWinVistaOrHigher(this OperatingSystem OS)
{
  return (OS.Platform == PlatformID.Win32NT)
    && (OS.Version.Major >= 6);
}

public static bool IsWin7OrHigher(this OperatingSystem OS)
{
  return (OS.Platform == PlatformID.Win32NT)
    && ((OS.Version.Major > 6) || ((OS.Version.Major == 6) && (OS.Version.Minor >= 1)));
}

public static bool IsWin8OrHigher(this OperatingSystem OS)
{
  return (OS.Platform == PlatformID.Win32NT)
    && ((OS.Version.Major > 6) || ((OS.Version.Major == 6) && (OS.Version.Minor >= 2)));
}

Verwendungszweck:

if (Environment.OSVersion.IsWinXPOrHigher())
{
  // do stuff
}

if (Environment.OSVersion.IsWinVistaOrHigher())
{
  // do stuff
}

if (Environment.OSVersion.IsWin7OrHigher())
{
  // do stuff
}

if (Environment.OSVersion.IsWin8OrHigher())
{
  // do stuff
}
0
takrl

Smalltalk-Stil if/else in c #.

Sie können dies unter jeder Lizenz, die Sie verwenden, auf codeplex setzen

using System;
namespace SmalltalkBooleanExtensionMethods
{

    public static class BooleanExtension
    {
        public static T ifTrue<T> (this bool aBoolean, Func<T> method)
        {
        if (aBoolean)
            return (T)method();
        else
            return default(T);
    }

        public static void ifTrue (this bool aBoolean, Action method)
        {
            if (aBoolean)
                method();
        }


        public static T ifFalse<T> (this bool aBoolean, Func<T> method)
        {
            if (!aBoolean)
                return (T)method();
            else
                return default(T);
        }

        public static void ifFalse (this bool aBoolean, Action method)
        {
            if (!aBoolean)
                method();
        }


        public static T ifTrueifFalse<T> (this Boolean aBoolean, Func<T> methodA, Func<T> methodB)
        {
            if (aBoolean)
                return (T)methodA();
            else
                return (T)methodB();
        }

        public static void ifTrueifFalse (this Boolean aBoolean, Action methodA, Action methodB)
        {
            if (aBoolean)
                methodA();
            else
                methodB();
        }

    }


}

Sie haben wahrscheinlich bereits eine timesRepeat-Methode, aber die ist da drin.

using System;

namespace SmalltalkBooleanExtensionMethods
{
    public static class IntExtension
    {
        public static int timesRepeat<T>(this int x, Func<T> method)
        {
            for (int i = x; i > 0; i--)
            {
                method();
            }

            return x;
        }

        public static int timesRepeat(this int x, Action method)
        {
            for (int i = x; i > 0; i--)
            {
                method();
            }

            return x;
        }
    }
}

Nunit-Tests

using System;
using SmalltalkBooleanExtensionMethods;
using NUnit.Framework;

namespace SmalltalkBooleanExtensionMethodsTest
{
    [TestFixture]
    public class SBEMTest
    {
        int i;
        bool itWorks;

        [SetUp]
        public void Init()
        {

            i = 0;
            itWorks = false;
        }

        [Test()]
        public void TestifTrue()
        {

            itWorks = (true.ifTrue(() => true));
            Assert.IsTrue(itWorks);
        }
        [Test()]
        public void TestifFalse()
        {
            itWorks = (false.ifFalse(() => true));
            Assert.IsTrue(itWorks);
        }

        [Test()]
        public void TestifTrueifFalse()
        {
            itWorks = false.ifTrueifFalse(() => false, () => true);
            Assert.IsTrue(itWorks);
            itWorks = false;
            itWorks = true.ifTrueifFalse(() => true, () => false);
            Assert.IsTrue(itWorks);
        }

        [Test()]
        public void TestTimesRepeat()
        {
            (5).timesRepeat(() => i = i + 1);
            Assert.AreEqual(i, 5);
        }

        [Test()]
        public void TestVoidMethodIfTrue()
        {

            true.ifTrue(() => SetItWorksBooleanToTrue());
            Assert.IsTrue(itWorks);
        }

        [Test()]
        public void TestVoidMethodIfFalse()
        {

            false.ifFalse(() => SetItWorksBooleanToTrue());
            Assert.IsTrue(itWorks);
        }

        public void TestVoidMethodIfTrueIfFalse()
        {
            true.ifTrueifFalse(() => SetItWorksBooleanToTrue(), () => SetItWorksBooleanToFalse());
            false.ifTrueifFalse(() => SetItWorksBooleanToFalse(), () => SetItWorksBooleanToTrue());
            Assert.IsTrue(itWorks);

        }

        public void TestVoidMethodTimesRepeat()
        {
            (5).timesRepeat(() => AddOneToi());
            Assert.AreEqual(i, 5);
        }

        public void SetItWorksBooleanToTrue()
        {
            itWorks = true;
        }

        public void SetItWorksBooleanToFalse()
        {
            itWorks = false;
        }

        public void AddOneToi()
        {
            i = i + 1;
        }
    }
}
0

Ich verwende die folgenden Erweiterungen, um alle Sammlungen zu erweitern (vielleicht findet jemand diese nützlich):

/// <summary>
/// Collection Helper
/// </summary>
/// <remarks>
/// Use IEnumerable by default, but when altering or getting item at index use IList.
/// </remarks>
public static class CollectionHelper
{

    #region Alter;

    /// <summary>
    /// Swap item to another place
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="IndexA">Index a</param>
    /// <param name="IndexB">Index b</param>
    /// <returns>New collection</returns>
    public static IList<T> Swap<T>(this IList<T> @this, Int32 IndexA, Int32 IndexB)
    {
        T Temp = @this[IndexA];
        @this[IndexA] = @this[IndexB];
        @this[IndexB] = Temp;
        return @this;
    }

    /// <summary>
    /// Swap item to the left
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="Index">Index</param>
    /// <returns>New collection</returns>
    public static IList<T> SwapLeft<T>(this IList<T> @this, Int32 Index)
    {
        return @this.Swap(Index, Index - 1);
    }

    /// <summary>
    /// Swap item to the right
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="Index">Index</param>
    /// <returns>New collection</returns>
    public static IList<T> SwapRight<T>(this IList<T> @this, Int32 Index)
    {
        return @this.Swap(Index, Index + 1);
    }

    #endregion Alter;

    #region Action;

    /// <summary>
    /// Execute action at specified index
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="Index">Index</param>
    /// <param name="ActionAt">Action to execute</param>
    /// <returns>New collection</returns>
    public static IList<T> ActionAt<T>(this IList<T> @this, Int32 Index, Action<T> ActionAt)
    {
        ActionAt(@this[Index]);
        return @this;
    }

    #endregion Action;

    #region Randomize;

    /// <summary>
    /// Take random items
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="Count">Number of items to take</param>
    /// <returns>New collection</returns>
    public static IEnumerable<T> TakeRandom<T>(this IEnumerable<T> @this, Int32 Count)
    {
        return @this.Shuffle().Take(Count);
    }

    /// <summary>
    /// Take random item
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <returns>Item</returns>
    public static T TakeRandom<T>(this IEnumerable<T> @this)
    {
        return @this.TakeRandom(1).Single();
    }

    /// <summary>
    /// Shuffle list
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <returns>New collection</returns>
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> @this)
    {
        return @this.OrderBy(Item => Guid.NewGuid());
    }

    #endregion Randomize;

    #region Navigate;

    /// <summary>
    /// Get next item in collection and give first item, when last item is selected;
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="Index">Index in collection</param>
    /// <returns>Next item</returns>
    public static T Next<T>(this IList<T> @this, ref Int32 Index)
    {
        Index = ++Index >= 0 && Index < @this.Count ? Index : 0;
        return @this[Index];
    }

    /// <summary>
    /// Get previous item in collection and give last item, when first item is selected;
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <param name="Index">Index in collection</param>
    /// <returns>Previous item</returns>
    public static T Previous<T>(this IList<T> @this, ref Int32 Index)
    {
        Index = --Index >= 0 && Index < @this.Count ? Index : @this.Count - 1;
        return @this[Index];
    }

    #endregion Navigate;

    #region Clone;

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T">Collection type</typeparam>
    /// <param name="this">Collection</param>
    /// <returns>Cloned collection</returns>
    public static IEnumerable<T> Clone<T>(this IEnumerable<T> @this) where T : ICloneable
    {
        return @this.Select(Item => (T)Item.Clone());
    }

    #endregion Clone;

    #region String;

    /// <summary>
    /// Joins multiple string with Separator
    /// </summary>
    /// <param name="this">Collection</param>
    /// <param name="Separator">Separator</param>
    /// <returns>Joined string</returns>
    public static String Join(this IEnumerable<String> @this, String Separator = "")
    {
        return String.Join(Separator, @this);
    }

    #endregion String;

}
0
jerone
public static class StringHelper
{
    public static String F(this String str, params object[] args)
    {
        return String.Format(str, args);
    }
}

Verwendung wie:

"Say {0}".F("Hello");
0

Sql-Server hat ein Limit von ~ 2000 Parametern, was sehr schwierig ist, wenn Sie über 10.000 IDs verfügen und möchten, dass die Datensätze mit ihnen verbunden sind. Ich habe diese Methoden geschrieben, die gestapelte Listen von IDs akzeptieren und wie folgt aufgerufen werden:

List<Order> orders = dataContext.Orders.FetchByIds(
  orderIdChunks,
  list => row => list.Contains(row.OrderId)
);

List<Customer> customers = dataContext.Orders.FetchByIds(
  orderIdChunks,
  list => row => list.Contains(row.OrderId),
  row => row.Customer
);

public static List<ResultType> FetchByIds<RecordType, ResultType>(
    this IQueryable<RecordType> querySource,
    List<List<int>> IdChunks,
    Func<List<int>, Expression<Func<RecordType, bool>>> filterExpressionGenerator,
    Expression<Func<RecordType, ResultType>> projectionExpression
    ) where RecordType : class
{
    List<ResultType> result = new List<ResultType>();
    foreach (List<int> chunk in IdChunks)
    {
        Expression<Func<RecordType, bool>> filterExpression =
            filterExpressionGenerator(chunk);

        IQueryable<ResultType> query = querySource
            .Where(filterExpression)
            .Select(projectionExpression);

        List<ResultType> rows = query.ToList();
        result.AddRange(rows);
    }

    return result;
}

public static List<RecordType> FetchByIds<RecordType>(
    this IQueryable<RecordType> querySource,
    List<List<int>> IdChunks,
    Func<List<int>, Expression<Func<RecordType, bool>>> filterExpressionGenerator
    ) where RecordType : class
{
    Expression<Func<RecordType, RecordType>> identity = r => r;

    return FetchByIds(
        querySource,
        IdChunks,
        filterExpressionGenerator,
        identity
        );
}
0
Amy B

Vielleicht sind die nützlichsten Erweiterungsmethoden, die ich geschrieben und verwendet habe, hier:

http://www.codeproject.com/KB/cs/fun-with-cs-extensions.aspx?msg=2838918#xx2838918xx

0
Tony Tanzillo

Vergleichen Sie die Gleichheit zweier Objekte, ohne (notwendigerweise) Equals zu überschreiben oder IEquatable <> zu implementieren.

Warum würdest du das tun wollen? Wenn Sie wirklich wissen möchten, ob zwei Objekte gleich sind, aber zu faul sind, um Equals(object) zu überschreiben oder IEquatable<T> Zu implementieren. Realistischerweise wäre die Implementierung von Equals per Hand äußerst mühsam, fehleranfällig und macht keinen Spaß, wenn Sie eine äußerst komplexe Klasse haben. Es hilft auch, wenn Sie sich nicht zu sehr für die Leistung interessieren.

Ich verwende derzeit IsEqualTo aus dem zweiten Grund - Ich habe eine Klasse mit vielen Eigenschaften, deren Typen andere benutzerdefinierte Klassen sind, von denen jede viele andere Eigenschaften hat, deren Typen andere benutzerdefinierte Klassen sind, ad infinitum . Werfen Sie in vielen dieser Klassen eine Reihe von Sammlungen ein, und die Implementierung von Equals(object) wird wirklich zu einem Albtraum.

Verwendungszweck:

if (myTerriblyComplexObject.IsEqualTo(myOtherTerriblyComplexObject))
{
    // Do something terribly interesting.
}

Um die Gleichheit festzustellen, mache ich zahlreiche Vergleiche. Ich unternehme jeden Versuch, das "Richtige" in der "richtigen" Reihenfolge zu tun. Die Vergleiche in der Reihenfolge sind:

  1. Verwenden Sie die statische Methode Equals(object, object). Wenn es true zurückgibt, geben Sie true zurück. Es wird true zurückgegeben, wenn die Referenzen identisch sind. Es wird auch true zurückgegeben, wenn thisObjectEquals(object) überschreibt.
  2. Wenn thisObject null ist, geben Sie false zurück. Wenn es null ist, können keine weiteren Vergleiche durchgeführt werden.
  3. Wenn thisObjectEquals(object) überschrieben hat, geben Sie false zurück. Da es Equals überschreibt, muss es bedeuten, dass Equals in Schritt 1 ausgeführt und false zurückgegeben wurde. Wenn sich jemand die Mühe gemacht hat, Equals zu überschreiben, sollten wir das respektieren und zurückgeben, was Equals zurückgibt.
  4. Wenn thisObject von IEquatable<T> Erbt, wobei otherObjectT zugewiesen werden kann, rufen Sie die Equals(T) -Methode mit Reflektion ab. Rufen Sie diese Methode auf und geben Sie ihren Rückgabewert zurück.
  5. Wenn beide Objekte IEnumerable sind, geben Sie mithilfe von IsEqualTo zum Vergleichen der Elemente zurück, ob dieselben Elemente in derselben Reihenfolge enthalten sind.
  6. Wenn die Objekte unterschiedliche Typen haben, geben Sie false zurück. Da wir jetzt wissen, dass thisObject keine Equals-Methode hat, gibt es keine Möglichkeit, zwei Objekte unterschiedlichen Typs realistisch als wahr zu bewerten.
  7. Wenn es sich bei den Objekten um einen Werttyp (Grundelement oder Struktur) oder eine Zeichenfolge handelt, geben Sie false zurück. Wir haben den Equals(object) Test bereits nicht bestanden - genug gesagt.
  8. Testen Sie für jede Eigenschaft von thisObject ihren Wert mit IsEqualTo. Wenn ein Wert false zurückgibt, wird false zurückgegeben. Wenn alle true zurückgeben, geben Sie true zurück.

String-Vergleiche könnten besser sein, sind aber einfach zu implementieren. Außerdem bin ich mir nicht zu 100% sicher, ob ich mit Strukturen richtig umgehe.

Hier ist ohne weiteres die Erweiterungsmethode:

/// <summary>
/// Provides extension methods to determine if objects are equal.
/// </summary>
public static class EqualsEx
{
    /// <summary>
    /// The <see cref="Type"/> of <see cref="string"/>.
    /// </summary>
    private static readonly Type StringType = typeof(string);

    /// <summary>
    /// The <see cref="Type"/> of <see cref="object"/>.
    /// </summary>
    private static readonly Type ObjectType = typeof(object);

    /// <summary>
    /// The <see cref="Type"/> of <see cref="IEquatable{T}"/>.
    /// </summary>
    private static readonly Type EquatableType = typeof(IEquatable<>);

    /// <summary>
    /// Determines whether <paramref name="thisObject"/> is equal to <paramref name="otherObject"/>.
    /// </summary>
    /// <param name="thisObject">
    /// This object.
    /// </param>
    /// <param name="otherObject">
    /// The other object.
    /// </param>
    /// <returns>
    /// True, if they are equal, otherwise false.
    /// </returns>
    public static bool IsEqualTo(this object thisObject, object otherObject)
    {
        if (Equals(thisObject, otherObject))
        {
            // Always check Equals first. If the object has overridden Equals, use it. This will also capture the case where both are the same reference.
            return true;
        }

        if (thisObject == null)
        {
            // Because Equals(object, object) returns true if both are null, if either is null, return false.
            return false;
        }

        var thisObjectType = thisObject.GetType();
        var equalsMethod = thisObjectType.GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance, null, new[] { ObjectType }, null);
        if (equalsMethod.DeclaringType == thisObjectType)
        {
            // thisObject overrides Equals, and we have already failed the Equals test, so return false.
            return false;
        }

        var otherObjectType = otherObject == null ? null : otherObject.GetType();

        // If thisObject inherits from IEquatable<>, and otherObject can be passed into its Equals method, use it.
        var equatableTypes = thisObjectType.GetInterfaces().Where(                                          // Get interfaces of thisObjectType that...
            i => i.IsGenericType                                                                            // ...are generic...
            && i.GetGenericTypeDefinition() == EquatableType                                                // ...and are IEquatable of some type...
            && (otherObjectType ==  null || i.GetGenericArguments()[0].IsAssignableFrom(otherObjectType))); // ...and otherObjectType can be assigned to the IEquatable's type.

        if (equatableTypes.Any())
        {
            // If we found any interfaces that meed our criteria, invoke the Equals method for each interface.
            // If any return true, return true. If all return false, return false.
            return equatableTypes
                .Select(equatableType => equatableType.GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance))
                .Any(equatableEqualsMethod => (bool)equatableEqualsMethod.Invoke(thisObject, new[] { otherObject }));
        }

        if (thisObjectType != StringType && thisObject is IEnumerable && otherObject is IEnumerable)
        {
            // If both are IEnumerable, check their items.
            var thisEnumerable = ((IEnumerable)thisObject).Cast<object>();
            var otherEnumerable = ((IEnumerable)otherObject).Cast<object>();

            return thisEnumerable.SequenceEqual(otherEnumerable, IsEqualToComparer.Instance);
        }

        if (thisObjectType != otherObjectType)
        {
            // If they have different types, they cannot be equal.
            return false;
        }

        if (thisObjectType.IsValueType || thisObjectType == StringType)
        {
            // If it is a value type, we have already determined that they are not equal, so return false.
            return false;
        }

        // Recurse into each public property: if any are not equal, return false. If all are true, return true.
        return !(from propertyInfo in thisObjectType.GetProperties()
                 let thisPropertyValue = propertyInfo.GetValue(thisObject, null)
                 let otherPropertyValue = propertyInfo.GetValue(otherObject, null)
                 where !thisPropertyValue.IsEqualTo(otherPropertyValue)
                 select thisPropertyValue).Any();
    }

    /// <summary>
    /// A <see cref="IEqualityComparer{T}"/> to be used when comparing sequences of collections.
    /// </summary>
    private class IsEqualToComparer : IEqualityComparer<object>
    {
        /// <summary>
        /// The singleton instance of <see cref="IsEqualToComparer"/>.
        /// </summary>
        public static readonly IsEqualToComparer Instance;

        /// <summary>
        /// Initializes static members of the <see cref="EqualsEx.IsEqualToComparer"/> class.
        /// </summary>
        static IsEqualToComparer()
        {
            Instance = new IsEqualToComparer();
        }

        /// <summary>
        /// Prevents a default instance of the <see cref="EqualsEx.IsEqualToComparer"/> class from being created.
        /// </summary>
        private IsEqualToComparer()
        {
        }

        /// <summary>
        /// Determines whether the specified objects are equal.
        /// </summary>
        /// <param name="x">
        /// The first object to compare.
        /// </param>
        /// <param name="y">
        /// The second object to compare.
        /// </param>
        /// <returns>
        /// true if the specified objects are equal; otherwise, false.
        /// </returns>
        bool IEqualityComparer<object>.Equals(object x, object y)
        {
            return x.IsEqualTo(y);
        }

        /// <summary>
        /// Not implemented - throws an <see cref="NotImplementedException"/>.
        /// </summary>
        /// <param name="obj">
        /// The <see cref="object"/> for which a hash code is to be returned.
        /// </param>
        /// <returns>
        /// A hash code for the specified object.
        /// </returns>
        int IEqualityComparer<object>.GetHashCode(object obj)
        {
            throw new NotImplementedException();
        }
    }
}
0
fre0n

Oh, warum nicht! Hier ist eine Erweiterung zu IList (kann nicht IEnumerable sein, weil ich listenspezifische Funktionen verwende) für die Sortierung des Einfügens.

internal static class SortingHelpers
{
    /// <summary>
    /// Performs an insertion sort on this list.
    /// </summary>
    /// <typeparam name="T">The type of the list supplied.</typeparam>
    /// <param name="list">the list to sort.</param>
    /// <param name="comparison">the method for comparison of two elements.</param>
    /// <returns></returns>
    public static void InsertionSort<T>(this IList<T> list, Comparison<T> comparison)
    {
        for (int i = 2; i < list.Count; i++)
        {
            for (int j = i; j > 1 && comparison(list[j], list[j - 1]) < 0; j--)
            {
                T tempItem = list[j];
                list.RemoveAt(j);
                list.Insert(j - 1, tempItem);
            }
        }
    }
}

Ein Beispiel:

List<int> list1 = { 3, 5, 1, 2, 9, 4, 6 };
list1.InsertionSort((a,b) => a - b);
//list is now in order of 1,2,3,4,5,6,9
0
RCIX