Question Quelles sont vos méthodes d'extension préférées pour C #? (codeplex.com/extensionoverflow)


Faisons une liste de réponses où vous postez votre excellent et favori méthodes d'extension.

L'exigence est que le code complet doit être affiché et un exemple et une explication sur la façon de l'utiliser.

Compte tenu de l’intérêt marqué pour ce sujet, j’ai créé un projet Open Source appelé extensionoverflow sur Codeplex.

Veuillez marquer vos réponses en acceptant de mettre le code dans le projet Codeplex.

Veuillez poster le code source complet et non un lien.

Codeplex News:

24.08.2010 La page Codeplex est maintenant ici: http://extensionoverflow.codeplex.com/

11.11.2008 XmlSerialize / XmlDeserialize est maintenant Mis en œuvre et Unité testée.

11.11.2008 Il y a encore de la place pour plus de développeurs. ;-) Adhérer!

11.11.2008 Troisième contributeur rejoint ExtensionOverflow, Bienvenue à BKristensen

11.11.2008 FormatWith est maintenant Mis en œuvre et Unité testée.

09.11.2008 Deuxième contributeur rejoint ExtensionOverflow. Bienvenue à chakrit.

09.11.2008 Nous avons besoin de plus de développeurs. ;-)

09.11.2008 ThrowIfArgumentIsNull maintenant Mis en œuvre et Unité testée sur Codeplex.


478


origine


Réponses:


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

Me permet de remplacer:

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

Avec:

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



J'ai diverses méthodes d'extension dans mon MiscUtil projet (source complète est disponible là-bas - je ne vais pas le répéter ici). Mes favoris, dont certains impliquent d'autres classes (telles que les gammes):

Date et heure - principalement pour les tests unitaires. Je ne suis pas sûr de les utiliser en production :)

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

Gammes et stepping - un grand merci à Marc Gravell pour son trucs d'opérateur pour rendre cela possible:

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

Comparaisons:

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

Vérification de l'argument:

x.ThrowIfNull("x");

LINQ to XML appliqué aux types anonymes (ou autres types avec des propriétés appropriées):

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

Push LINQ - serait trop long à expliquer ici, mais recherchez-le.


160



raccourci string.Format:

public static class StringExtensions
{
    // Enable quick and more natural string.Format calls
    public static string F(this string s, params object[] args)
    {
        return string.Format(s, args);
    }
}

Exemple:

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

Pour aller rapidement copier-coller ici.

Ne trouvez-vous pas plus naturel de taper "some string".F("param") au lieu de string.Format("some string", "param") ?

Pour plus lisible nom, essayez l'une de ces suggestions:

s = "Hello {0} world {1}!".Fmt("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatBy("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatWith("Stack", "Overflow");
s = "Hello {0} world {1}!".Display("Stack", "Overflow");
s = "Hello {0} world {1}!".With("Stack", "Overflow");

..


147



Est-ce que ce sont des utilisations?

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

public static T OneOf<T>(this Random rng, params T[] things)
{
    return things[rng.Next(things.Length)];
}

Random rand;
bool luckyDay = rand.CoinToss();
string babyName = rand.OneOf("John", "George", "Radio XBR74 ROCKS!");

89



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

Exemple:

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

76



La méthode d'extension:

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

La méthode s'applique à tous les types et vous permet d'ajouter une plage d'éléments à une liste en tant que paramètres.

Exemple:

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

58



Mettez-le bien dans le projet codeplex.

Sérialisation / désérialisation des objets en XML:

/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
    if (obj == null) throw new ArgumentNullException("obj");

    var serializer = new XmlSerializer(typeof(T));
    using (var writer = new StringWriter())
    {
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
}

/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
    if (xml == null) throw new ArgumentNullException("xml");

    var serializer = new XmlSerializer(typeof(T));
    using (var reader = new StringReader(xml))
    {
        try { return (T)serializer.Deserialize(reader); }
        catch { return null; } // Could not be deserialized to this type.
    }
}

55



ForEach pour IEnumerables

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

Exemple naïf:

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

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

Exemple cool:

// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
    .ForEach(item => {
        item.Number = 1;
        item.Str = "Hello World!";
    });

Remarque:

Ce n'est pas comme Select car Select  attend votre fonction pour retourner quelque chose comme pour transformer dans une autre liste.

ForEach vous permet simplement d'exécuter quelque chose pour chacun des éléments sans aucune transformation / manipulation de données.

J'ai fait cela afin que je puisse programmer dans un style plus fonctionnel et j'ai été surpris que List ait un ForEach alors que IEnumerable ne le fait pas.

Mettez ceci dans le projet codeplex


46