GOOGLE ADS

Dienstag, 12. April 2022

So verwenden Sie den neuen Operator mit einer Vorlage in C#

Ich versuche herauszufinden, wie man Vorlagen in C# verwendet. Ich habe das geschrieben:

public static List<TValue> deepCopyList<TValue>(List<TValue> src)
{
List<TValue> arr = new List<TValue>();
for (int i = 0; i < src.Count; i++)
{
arr.Add(new TValue(src[i])); //Error on this line
}
return arr;
}

Aber ich bekomme einen Fehler:

Fehler CS0304: Es kann keine Instanz des Variablentyps „TValue" erstellt werden, da er nicht über die new()-Einschränkung verfügt


Lösung des Problems

#1: Neue Einschränkung mit Schnittstelle

Fügen Sie eine Einschränkung hinzu, TValueum dem Compiler mitzuteilen, dass er einen parameterlosen Konstruktor hat. Sie können dies tun, indem Sie das Schlüsselwort newzur Einschränkung von hinzufügen TValue. Auf diese Weise können Sie zumindest einen Gegenstand konstruieren.

Sie können keine Parameter generischer Parametertypen verwenden. Sie können jedoch eine andere Einschränkung verwenden, um einige Eigenschaften zu definieren:

public interface IMyValue<TValue>
{
void CopyFrom(TValue original);
}
public static List<TValue> deepCopyList<TValue>(List<TValue> src)
where TValue: IMyValue<TValue>, new() // <== Setting the constraints of TValue.
{
List<TValue> arr = new List<TValue>();
for (int i = 0; i < src.Count; i++)
{
TValue value = new TValue();
value.CopyFrom(src[i]);
arr.Add(value); // No error.
}
return arr;
}

#2: Verwendung von ICloneable

Es gibt eine zweite Lösung, und es ist ein bisschen die gleiche. Machen Sie den Wert für das Klonen selbst verantwortlich, indem Sie Folgendes verwenden ICloneable:

public static List<TValue> deepCopyList<TValue>(List<TValue> src)
where TValue: ICloneable // <== Setting the constraints of TValue.
{
List<TValue> arr = new List<TValue>();
for (int i = 0; i < src.Count; i++)
{
TValue value = (TValue)src[i].Clone();
arr.Add(value); // No error.
}
return arr;
}

#3: Verwendung von Aktivator

Da Sie jedoch einen tiefen Klon erstellen möchten, gibt es einen anderen Weg, indem Sie die Activator. Diese Methode ist NICHT typsicher und kann Laufzeitausnahmen erzeugen, wenn der Typ diesen Konstruktoraufruf nicht unterstützt:

public static List<TValue> deepCopyList<TValue>(List<TValue> src)
{
List<TValue> arr = new List<TValue>();
for (int i = 0; i < src.Count; i++)
{
TValue value = (TValue)Activator.CreateInstance(typeof(TValue), src[i]);
arr.Add(value); // Possible runtime rror.
}
return arr;
}

Die obige Methode kann auch durch die Verwendung von Reflektion ersetzt werden und die richtige erhalten ConstructorInfound diese verwenden, um neue Elemente zu erstellen. Es ist dasselbe, was dasselbe Activatortut und dasselbe Risiko hat.

BTW: In C# heißt es 'generic', nicht 'template' wie in C++.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...