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.

0voto

NeverFade Punkte 1

Wenn Sie persisch sprechen und die Zahlen den Benutzern in persischer Sprache 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;
        }

0voto

John Punkte 1094

Wir haben ein Verteilungswerkzeug für die Verteilung zwischen Umgebungen. Da die Dateien zwar als geändert markiert werden können, aber nicht wirklich unterschiedlich sind, habe ich mir das hier ausgedacht:

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

0voto

Amy B Punkte 104656

Sql-Server hat ein Limit von ~2000 Parametern, was ein Problem ist, wenn man 10k Ids hat und die damit verbundenen Datensätze haben möchte. Ich schrieb diese Methoden, die gebündelte 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
        );
}

0voto

fre0n Punkte 1825

Vergleichen Sie die Gleichheit von zwei Objekten, ohne (notwendigerweise) Equals zu überschreiben oder IEquatable<> zu implementieren.

Warum wollen Sie das tun? Wenn Sie wirklich wissen wollen, ob zwei Objekte gleich sind, aber zu faul sind, die Equals(object) oder umsetzen IEquatable<T> . Oder, realistischer, wenn Sie eine furchtbar komplexe Klasse haben und die Implementierung von Equals von Hand extrem mühsam, fehleranfällig und nicht angenehm zu pflegen wäre. Es hilft auch, wenn Sie sich nicht zu sehr um die Leistung kümmern.

Ich verwende derzeit IsEqualTo wegen des zweiten Grundes - 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. Fügen Sie eine Reihe von Sammlungen in vielen dieser Klassen hinzu, und die Implementierung von Equals(object) wird wahrhaftig zu einem Albtraum.

Verwendung:

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

Um die Gleichheit festzustellen, führe ich zahlreiche Vergleiche durch. Ich bemühe mich, den "richtigen" Vergleich in der "richtigen" Reihenfolge durchzuführen. Die Vergleiche, in der Reihenfolge sind:

  1. Verwenden Sie die statische Equals(object, object) Methode. Wenn sie true liefert, wird true zurückgegeben. Es wird true zurückgegeben, wenn die Referenzen gleich sind. Sie gibt auch true zurück, wenn thisObject übersteuert Equals(object) .
  2. Si thisObject null ist, wird false zurückgegeben. Wenn es null ist, können keine weiteren Vergleiche durchgeführt werden.
  3. Si thisObject hat außer Kraft gesetzt Equals(object) , return false. Da es Equals übersteuert, muss es bedeuten, dass Equals in Schritt 1 ausgeführt wurde und false zurückgegeben hat. Wenn sich jemand die Mühe gemacht hat, Equals außer Kraft zu setzen, sollten wir das respektieren und das zurückgeben, was Equals zurückgibt.
  4. Si thisObject erbt von IEquatable<T> , donde otherObject können zugeordnet werden zu T erhalten die Equals(T) Methode mit Hilfe der Reflexion. Rufen Sie diese Methode auf und geben Sie ihren Rückgabewert zurück.
  5. Wenn beide Objekte IEnumerable zurückgeben, ob sie die gleichen Elemente in der gleichen Reihenfolge enthalten, wobei IsEqualTo zum Vergleich der Elemente verwendet wird.
  6. Wenn die Objekte unterschiedliche Typen haben, wird false zurückgegeben. Da wir nun wissen, dass thisObject nicht über eine Equals-Methode verfügt, gibt es keine Möglichkeit, zwei Objekte unterschiedlichen Typs realistisch als wahr zu bewerten.
  7. Handelt es sich bei den Objekten um einen Werttyp (primitiv oder struct) oder eine Zeichenkette, wird false zurückgegeben. Wir haben bereits die Equals(object) Test - genug gesagt.
  8. Für jede Eigenschaft von thisObject testen Sie seinen Wert mit IsEqualTo. Wenn einer der Werte false ist, wird false zurückgegeben. Wenn alle true zurückgeben, wird true zurückgegeben.

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

Im Folgenden wird die Methode der Erweiterung kurz erläutert:

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

0voto

HuseyinUslu Punkte 4045

Und hier ist die control-invoke-Erweiterung, die ich regelmäßig verwende;

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

Probe;

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

die threadübergreifende GUI-Aktualisierungen ermöglicht.

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