478 Stimmen

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 .

Die Anforderung ist, dass der vollständige Code mit einem Beispiel und einer Erklärung, wie er zu verwenden ist, veröffentlicht werden muss.

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

Bitte markieren Sie Ihre Antworten mit der Zustimmung, den Code in das Codeplex-Projekt zu stellen.

Bitte posten Sie den vollständigen Quellcode und nicht nur einen Link.

Codeplex Nachrichten:

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

11.11.2008 XmlSerialize / XmlDeserialize ist jetzt Implementiert y Einheit getestet .

11.11.2008 Es gibt noch Platz für weitere Entwickler ;-) JETZT anmelden!

11.11.2008 Dritter Beitragszahler beigetreten ExtensionOverflow , willkommen bei BKristensen

11.11.2008 FormatWith ist jetzt Implementiert y Einheit getestet .

09.11.2008 Zweiter Beitragszahler beigetreten ExtensionOverflow . willkommen bei chakrit .

09.11.2008 Wir brauchen mehr Entwickler ;-)

09.11.2008 ThrowIfArgumentIsNull in jetzt Implementiert y Einheit getestet auf Codeplex.

6voto

Ich verwende diese Erweiterung Methode in der Regel mit anonymen Typen, um ein Wörterbuch ala Ruby erhalten

public static Dictionary<string, object> ToDictionary(this object o)
{
    var dictionary = new Dictionary<string, object>();

    foreach (var propertyInfo in o.GetType().GetProperties())
    {
        if (propertyInfo.GetIndexParameters().Length == 0)
        {
            dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(o, null));
        }
    }

    return dictionary;
}

Sie können es verwenden

var dummy = new { color = "#000000", width = "100%", id = "myid" };
Dictionary<string, object> dict = dummy.ToDictionary();

Und mit einer erweiterten Methode als

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (T item in source)
    {
        action(item);
    }
}

Du kannst es schaffen

dummy.ToDictionary().ForEach((p) => Console.Write("{0}='{1}' ", p.Key, p.Value));

Ausgabe

color='#000000' width='100%' id='myid'

5voto

Jordão Punkte 53117

Sie alle wissen wahrscheinlich bereits, dass eine interessante Verwendung für Erweiterungsmethoden die Verwendung als Art von Mixin . Einige Erweiterungsmethoden, wie die XmlSerializable Sie verschmutzen fast jede Klasse, und für die meisten von ihnen macht es keinen Sinn, wie Thread y SqlConnection .

Einige Funktionen sollten ausdrücklich in die Klassen gemischt, die dies wünschen. Ich schlage eine neue Schreibweise zu dieser Art von Typ, mit dem M Vorwahl.

El XmlSerializable dann ist dies:

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

Eine Klasse mischt sie dann unter:

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

Und die Verwendung ist einfach:

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

Wenn Ihnen die Idee gefällt, können Sie einen neuen Namespace für nützliche Mixins im Projekt erstellen. Was halten Sie davon?

Oh, und übrigens, ich denke, die meisten Erweiterungsmethoden sollten explizit auf Null testen .

5voto

Mark Cidade Punkte 95914
static string Format( this string str,
                    , params Expression<Func<string,object>>[] args)
{
    var parameters = args.ToDictionary
                        ( e=>string.Format("{{{0}}}",e.Parameters[0].Name)
                        , e=>e.Compile()(e.Parameters[0].Name));

    var sb = new StringBuilder(str);
    foreach(var kv in parameters)
    {
        sb.Replace( kv.Key
                  , kv.Value != null ? kv.Value.ToString() : "");
    }

    return sb.ToString();
}

Mit der obigen Erweiterung können Sie dies schreiben:

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

und Sie erhalten "foo 2 System.Object ".

5voto

Mark Maxham Punkte 1461

Einfach, aber schöner als "Enumerable.Range", IMHO:

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

5voto

KeithS Punkte 67713

Hier ist ein weiteres Paar, für das ich endlos Verwendung gefunden habe:

public static T ObjectWithMin<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
    where T : class
    where TResult : IComparable
{
    if (!sequence.Any()) return null;

    //get the first object with its predicate value
    var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
    //compare against all others, replacing the accumulator with the lesser value
    //tie goes to first object found
    return
        sequence.Select(x => new {Object = x, Value = predicate(x)})
            .Aggregate(seed,(acc, x) => acc.Value.CompareTo(x.Value) <= 0 ? acc : x).Object;
}

public static T ObjectWithMax<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
    where T : class
    where TResult : IComparable
{
    if (!sequence.Any()) return null;

    //get the first object with its predicate value
    var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
    //compare against all others, replacing the accumulator with the greater value
    //tie goes to last object found
    return
        sequence.Select(x => new {Object = x, Value = predicate(x)})
            .Aggregate(seed, (acc, x) => acc.Value.CompareTo(x.Value) > 0 ? acc : x).Object;
}

Verwendung:

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

Diese Methoden ersetzen im Wesentlichen Verwendungen wie

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

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

var minValue = myList.Min(x=>x.PropA);
var myObject = myList.Where(x=>x.PropA == minValue).FirstOrDefault(); //not a one-liner, and though linear and stable it's slower (evaluates the enumerable twice)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X