Frage

Hat C# haben die Erweiterung Eigenschaften?

Zum Beispiel kann ich hinzufügen eine Erweiterung Eigenschaft DateTimeFormatInfo genannt ShortDateLongTimeFormat die würde zurück ShortDatePattern + " " + LongTimePattern?

War es hilfreich?

Lösung

Nein, sie existieren in nicht C # 3.0 und wird nicht in 4.0 hinzugefügt werden. Es ist auf der Liste des Features für C # will, so dass es zu einem späteren Zeitpunkt hinzugefügt werden.

An diesem Punkt das Beste, was Sie tun können, ist getXXX Stil Erweiterungsmethoden.

Andere Tipps

Nein, sie sind nicht vorhanden.

Ich weiß, dass das C # Team wurde sie an einem Punkt (oder zumindest Eric Lippert war) unter Berücksichtigung - zusammen mit der Erweiterung Errichter und Betreiber (die eine Weile dauern kann, den Kopf Runde zu bekommen, aber sie sind cool ...) jedoch ich habe keine Beweise gesehen, dass sie einen Teil von C # 4 sein werden.

EDIT: Sie schienen nicht in C # 5, und ab Juli 2014 sieht es nicht wie es in C # 6 entweder sein wird

.

Eric Lippert , der Haupt Entwickler auf dem C # -Compiler-Team bei Microsoft bis November 2012 darüber gebloggt in Oktober 2009:

Für den moment ist es immer noch nicht out of the box unterstützt durch die Roslyn-compiler - ...

Bis jetzt, die Erweiterung der Eigenschaften wurden nicht gesehen, wie wertvoll genug zu sein, enthalten die in den früheren Versionen von C# standard. C# 7 und C# 8.0 habe gesehen, diese als Vorschlag champion, aber es war nicht freigegeben, noch, vor allem, weil auch wenn es bereits eine Implementierung, die Sie machen wollen, es von Anfang an.

Aber es wird ...

Es ist ein Verlängerung Mitglieder Element in der C# 7 Arbeit Liste so kann es werden unterstützt werden in Naher Zukunft.Der aktuelle status der extension-Eigenschaft finden Sie auf Github unter " Verwandte Artikel.

Es gibt jedoch ein noch erfreulicheres Thema, das die "erweitern alles" mit einem Fokus auf besonders Eigenschaften und statische Klassen oder sogar Felder.

Außerdem können Sie eine Problemumgehung

Wie angegeben in dieser Artikel, Sie verwenden können die TypeDescriptor Fähigkeit zu befestigen, ein Attribut zu einem Objekt-Instanz zur Laufzeit.Es ist jedoch nicht mit der syntax der standard-Eigenschaften.
Es ist ein bisschen anders als nur syntaktischer Zucker hinzufügen eine Möglichkeit, um zu definieren, eine erweiterte Eigenschaft wie
string Data(this MyClass instance) als alias für die Verlängerung Methode
string GetData(this MyClass instance) wie es speichert die Daten in der Klasse.

Ich hoffe, dass C#7 voll funktionsfähige Erweiterung alles (Eigenschaften und Felder), jedoch in diesem Punkt, nur die Zeit wird erzählen.

Und fühlen Sie sich frei zu tragen, da die software von morgen kommen aus der community.

Update:August 2016

Als dotnet-team veröffentlicht was ist neu in C# 7.0 und aus einem Kommentar von Mads Torgensen:

Verlängerung Eigenschaften:wir hatten einen (genialen!) intern implementieren Sie über der Sommer wie ein experiment, zusammen mit anderen Arten von Verlängerung Mitglieder.Wir bleiben interessiert, aber es ist eine große Veränderung, und wir müssen sich sicher fühlen, dass es ist es Wert.

Es scheint, dass die Verlängerung der Eigenschaften und der anderen Mitglieder, sind immer noch gute Kandidaten werden in einer künftigen Version von Roslyn, aber vielleicht nicht der 7.0 ein.

Update:Mai 2017

Die Verlängerung Mitglieder geschlossen wurde als Duplikat von Erweiterung alles Problem die ist auch geschlossen.Die wichtigste Diskussion war in der Tat etwa die Art Erweiterbarkeit in einem weiten Sinne.Die Funktion ist nun verfolgt hier ein Vorschlag und entfernt wurde, aus 7.0 Meilenstein.

Update:August 2017 - C# 8.0 vorgeschlagene Funktion

Während es bleibt nur ein vorgeschlagen Funktion, wir haben jetzt ein klareres Bild von dem, was wäre die syntax.Beachten Sie, dass dies die neue syntax für die Erweiterung Methoden:

public interface IEmployee 
{
    public decimal Salary { get; set; }
}

public class Employee
{
    public decimal Salary { get; set; }
}

public extension MyPersonExtension extends Person : IEmployee
{
    private static readonly ConditionalWeakTable<Person, Employee> _employees = 
        new ConditionalWeakTable<Person, Employee>();


    public decimal Salary
    {
        get 
        {
            // `this` is the instance of Person
            return _employees.GetOrCreate(this).Salary; 
        }
        set 
        {
            Employee employee = null;
            if (!_employees.TryGetValue(this, out employee)
            {
                employee = _employees.GetOrCreate(this);
            }
            employee.Salary = value;
        }
    }
}

IEmployee person = new Person();
var salary = person.Salary;

Ähnlich wie die partielle Klassen, aber kompiliert als eine separate Klasse/Typ in einer anderen assembly.Hinweis: Sie werden auch in der Lage sein, statische Mitglieder und Betreiber diese Weise.Wie bereits in Mads Torgensen podcast, die Erweiterung wird nicht haben jeder Staat, der (so es nicht hinzufügen, private Instanz, die Mitglieder der Klasse), was bedeutet, dass Sie nicht in der Lage sein, private Instanz-Daten verknüpft, um die Instanz.Der Grund aufgerufen, für die, die es bedeuten würde, zu verwalten intern Wörterbüchern und es könnte schwierig werden (memory-management, etc...).Für diese, können Sie immer noch die TypeDescriptor/ConditionalWeakTable Technik, die früher beschrieben und mit der Eigenschaft, Erweiterung, versteckt es unter einem schönen Grundstück.

Syntax ist noch FREIBLEIBEND, impliziert dies Problem.Für Beispiel, extends ersetzt werden könnte durch for die paar können fühlen, mehr Natürliche und weniger java verwandt.

Update Dezember 2018 - Rollen, Erweiterungen und statische Schnittstelle Mitglieder

Erweiterung alles trifft nicht zu C# 8.0, weil einige Nachteile erklärt, wie Sie das Ende dieses GitHub-ticket.Also, es war eine Untersuchung, um die Gestaltung. Hier, Mads Torgensen erklärt, was sind Rollen und Erweiterungen und wie Sie sich unterscheidet:

Rollen ermöglichen den interfaces implementiert werden, die auf bestimmte Werte einer gegebenen Typ.Erweiterungen ermöglichen Schnittstellen implementiert werden, die auf alle Werte einer bestimmten Typ, der innerhalb einer spezifischen region-code.

Es kann gesehen werden auf eine Teilung der früheren Vorschlag in zwei Anwendungsfällen.Die neue syntax für die Erweiterung würde wie folgt Aussehen:

public extension ULongEnumerable of ulong
{
    public IEnumerator<byte> GetEnumerator()
    {
        for (int i = sizeof(ulong); i > 0; i--)
        {
            yield return unchecked((byte)(this >> (i-1)*8));
        }
    }
}

dann sind Sie in der Lage sein würde, dies zu tun:

foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
    WriteLine($"{e.Current:X}");
}

Und für eine statische Schnittstelle:

public interface IMonoid<T> where T : IMonoid<T>
{
    static T operator +(T t1, T t2);
    static T Zero { get; }
}

Fügen Sie ein Eigenschaft extension auf int und behandeln Sie die int als IMonoid<int>:

public extension IntMonoid of int : IMonoid<int>
{
    public static int Zero => 0;
}

Update (dank @chaost für den Hinweis dieses Update aus):

  

Mads Torgersen: „. Verlängerungs alles, was sie machen nicht in C # 8.0 Es wurde‚gefangen‘, wenn man so will, in einer sehr spannenden Debatte über die weitere Zukunft der Sprache und jetzt wollen wir sicherstellen, dass wir es nicht hinzufügen, in einer Weise, dass diese zukünftigen Möglichkeiten hemmt. Manchmal Sprache Design ist ein sehr langes Spiel! "

Quelle: Kommentarfeld in https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/


ich aufgehört zu zählen, wie viele Male im Laufe der Jahre habe ich diese Frage begann mit der Hoffnung, dies umgesetzt hat gesehen.

Nun, endlich können wir alle freuen! Microsoft wird diese C # 8 Release.

bei ihrer kommenden einführen

Also anstatt dies zu tun ...

public static class IntExtensions
{
   public static bool Even(this int value)
   {
        return value % 2 == 0;
   }
}

Wir werden schließlich in der Lage sein, es zu tun, wie so ...

public extension IntExtension extends int
{
    public bool Even => this % 2 == 0;
}

Quelle: https://blog.ndepend.com/c -8-0-Funktionen-Blick-Zukunft /

Wie @Psyonity erwähnt, können Sie die ConditionalWeakTable verwenden Eigenschaften vorhandener Objekte hinzuzufügen. In Kombination mit der dynamischen ExpandoObject, könnten Sie dynamische Erweiterungseigenschaften in wenigen Zeilen implementieren:

using System.Dynamic;
using System.Runtime.CompilerServices;

namespace ExtensionProperties
{
    /// <summary>
    /// Dynamically associates properies to a random object instance
    /// </summary>
    /// <example>
    /// var jan = new Person("Jan");
    ///
    /// jan.Age = 24; // regular property of the person object;
    /// jan.DynamicProperties().NumberOfDrinkingBuddies = 27; // not originally scoped to the person object;
    ///
    /// if (jan.Age &lt; jan.DynamicProperties().NumberOfDrinkingBuddies)
    /// Console.WriteLine("Jan drinks too much");
    /// </example>
    /// <remarks>
    /// If you get 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' you should reference Microsoft.CSharp
    /// </remarks>
    public static class ObjectExtensions
    {
        ///<summary>Stores extended data for objects</summary>
        private static ConditionalWeakTable<object, object> extendedData = new ConditionalWeakTable<object, object>();

        /// <summary>
        /// Gets a dynamic collection of properties associated with an object instance,
        /// with a lifetime scoped to the lifetime of the object
        /// </summary>
        /// <param name="obj">The object the properties are associated with</param>
        /// <returns>A dynamic collection of properties associated with an object instance.</returns>
        public static dynamic DynamicProperties(this object obj) => extendedData.GetValue(obj, _ => new ExpandoObject());
    }
}

Ein Anwendungsbeispiel ist in den XML-Kommentaren:

var jan = new Person("Jan");

jan.Age = 24; // regular property of the person object;
jan.DynamicProperties().NumberOfDrinkingBuddies = 27; // not originally scoped to the person object;

if (jan.Age < jan.DynamicProperties().NumberOfDrinkingBuddies)
{
    Console.WriteLine("Jan drinks too much");
}

jan = null; // NumberOfDrinkingBuddies will also be erased during garbage collection

Weil ich kürzlich diese benötigen, sah ich an der Quelle der Antwort in:

c # erweitern Klasse durch Hinzufügen von Eigenschaften

und erstellt eine dynamischere Version:

public static class ObjectExtenders
{
    static readonly ConditionalWeakTable<object, List<stringObject>> Flags = new ConditionalWeakTable<object, List<stringObject>>();

    public static string GetFlags(this object objectItem, string key)
    {
        return Flags.GetOrCreateValue(objectItem).Single(x => x.Key == key).Value;
    }

    public static void SetFlags(this object objectItem, string key, string value)
    {
        if (Flags.GetOrCreateValue(objectItem).Any(x => x.Key == key))
        {
            Flags.GetOrCreateValue(objectItem).Single(x => x.Key == key).Value = value;
        }
        else
        {
            Flags.GetOrCreateValue(objectItem).Add(new stringObject()
            {
                Key = key,
                Value = value
            });
        }
    }

    class stringObject
    {
        public string Key;
        public string Value;
    }
}

Es kann wahrscheinlich eine Menge (Namensgebung, dynamisch statt string) verbessert werden, verwende ich diese zur Zeit in CF 3.5 zusammen mit einem Hacky ConditionalWeakTable ( https://gist.github.com/Jan-WillemdeBruyn/db79dd6fdef7b9845e217958db98c4d4 )

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top