56 Stimmen

Wie geben Sie einen Standardtyp für Generics an?

Ich habe eine Klasse, die derzeit mehrere Methoden hat, die Integer-Parameter benötigen. Diese Integer werden den Operationen zugeordnet, die die Anwendung ausführen kann. Ich möchte die Klasse generisch machen, damit die Verbraucher der Klasse einen Enum-Typ angeben können, den sie mit allen Operationen darin haben, dann werden die Methoden Parameter dieses Enum-Typs entgegennehmen. Ich möchte jedoch, dass sie in der Lage sind, überhaupt keinen generischen Typ anzugeben und stattdessen standardmäßig auf Integers zurückgreifen, ohne dass sich die Syntax vom aktuellen Weg ändert. Ist das möglich?

2 Stimmen

Ist @Vilx- Lösung kein guter Ansatz und eine bessere Antwort?

2 Stimmen

@Max Schmeling Nachdem die erste Antwort gepostet wurde (und nachdem sie akzeptiert wurde, nehme ich an), wurde die richtige Antwort bereitgestellt. Zum Wohl der zukünftigen Suchenden, könnten Sie bitte die korrekte Antwort akzeptieren.

1 Stimmen

Ich weiß, dass diese Fragen von vor Ewigkeiten sind. Aber das ist ein Duplikat: stackoverflow.com/q/707780

10voto

Michael Meadows Punkte 26846

Sie können es nicht in der Definition der Klasse tun:

var foo = new MyGenericClass(); // Standardmäßig integer... das funktioniert nicht
var bar = new MyGenericClass(); // T ist ein MyEnum

Wenn Sie wirklich den impliziten Wert des Standardtyps als int schätzen, müssen Sie es mit einer statischen Factory-Methode tun, obwohl ich den Wert davon nicht sehe.

public class MyGenericClass
{
    public static MyGenericClass Create()
    {
        return new MyGenericClass();
    }
    public static MyGenericClass CreateDefault()
    {
        return new MyGenericClass();
    }
}

Im Folgenden sehen Sie, wie Sie wirklich nicht von dem oben Genannten profitieren.

var foo = MyGenericClass.Create();
var bar1 = MyGenericClass.CreateDefault(); // funktioniert nicht
var bar2 = MyGenericClass.CreateDefault(); // funktioniert, aber was ist der Sinn

Wenn Sie noch weiter gehen möchten, können Sie eine statische Factory-Klasse erstellen, die dieses Problem löst, aber das ist eine noch lächerlichere Lösung, wenn Sie es nur aus dem Grund tun, einen Standardtyp anzugeben:

public static class MyGenericClassFactory
{
    public static MyGenericClass Create()
    {
        return new MyGenericClass();
    }
    public static MyGenericClass Create()
    {
        return new MyGenericClass();
    }
}

var foo = MyGenericClassFactory.Create(); // jetzt haben wir eine int Definition
var bar = MyGenericClassFactory.Create();

2 Stimmen

Ja, ich möchte diese Komplexität nicht einführen. Das Standard ist nicht besonders wichtig, es wäre nur schön gewesen. Ich wusste nicht, wie man es gemacht hätte, aber ich wollte zuerst mit euch allen darüber sprechen, um sicherzugehen. Danke für die Antwort.

5 Stimmen

Diese Antwort ist unvollständig - sie verpasst den sehr einfachen Weg, das gewünschte Standardverhalten zu erreichen. Siehe Vilx-'s Antwort unten.

9voto

J.W. Punkte 17431

Behalten Sie Ihre Originalversion (nicht generische Version) bei und erstellen Sie eine generische Version davon.

Rufen Sie dann die generische Version von Ihrer nicht generischen Version aus auf.

void Main()
{
    DoSomething(2);
    DoSomething(EnumValue);
}

public void DoSomething(int test) {
    DoSomething(test);
}

// Andere Methoden und Klassen hier definieren
public void DoSomething(T test) {
    Console.WriteLine(test);
}

0 Stimmen

Der generische Parametertyp wird für alle Methoden gleich sein, daher hätte ich ihn gerne auf Klassenebene. Ich weiß, dass ich eine generische Version erstellen und dann davon erben könnte für die int-Version, aber ich hatte gehofft, alles in einem zu haben ... aber ich wusste nicht, wie das geht. Ich denke, es ist nicht so einfach möglich, wie ich gehofft habe.

2voto

mmx Punkte 400975

Der Compiler kann die Typargumente für Methoden in den meisten Fällen anhand des Typs der übergebenen Argumente ableiten:

public void DoSomething(T test) {
}

kann aufgerufen werden mit

DoSomething(4);                   // = DoSomething(4);
DoSomething(MyEnum.SomeValue);    // = DoSomething(MyEnum.SomeValue);

Übrigens können Sie auch nicht-generische Overloads einer generischen Methode haben.

0 Stimmen

Ich suche nach der Klasse, die "optional generisch" sein soll. Ich glaube nicht, dass es möglich ist, also muss ich einfach generische Methoden mit nicht-generischen Überladungen erstellen... Ich war auf der Suche nach diesem "SecurityContext sec = new SecurityContext();" (das würde es mit Ganzzahlen als Parameter erstellen, und dann "SecurityContext sec = new SecurityContext();", das es mit MyOperations als Parameter erstellen würde.

2voto

yugami Punkte 361

Ich bin mir sicher, dass du über dieses Thema hinweg bist, jedoch habe ich an einem ähnlichen Problem gearbeitet und diese Lösung gefunden, die einen Kontext von "verwenden" verwendet, mit dem ich nicht vertraut war. Sie müssen es in ihren Namespace setzen, also ist es nicht ganz perfekt.

namespace mygeneric
{
    public class SecurityContext
    {

    }
}

namespace mytest
{
    using SecurityContext = mygeneric.SecurityContext;
    using mygeneric;

    enum MyContexts
    {
        User,
        Admin
    }
    class MyTest
    {
        SecurityContext myDefaultContext;
        SecurityContext mySpecialContext;
    }
}

1 Stimmen

Dies ist sehr cool und würde wahrscheinlich für böse Zwecke verwendet werden. :-)

0voto

Der Compiler kann die Typargumente für Felder in den meisten Fällen anhand des Typs der übergebenen Argumente ableiten:

import lombok.Data;

@Data
public class MyClass {

    private T myField;
}

kann verwendet werden als,

MyClass myClass = new MyClass();
String abc = "Hallo Welt!";
myClass.setMyField(abc);
System.out.println("Test generische Klasse mit generischem Feld = " + myGenericClass.getMyField());

und das sollte zu folgendem Ergebnis führen,

Test generische Klasse mit generischem Feld = Hallo Welt!

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