7 Stimmen

Warum kann ich nicht erzwingen, dass abgeleitete Klassen parameterlose Konstruktoren haben?

Ich versuche, Folgendes zu tun:

class Program
{
    static void Main(string[] args)
    {
        foo<baz> fooObject = new foo<baz>();
        AnotherClass<baz> _baz = new AnotherClass<baz>();
        _baz.testMethod(fooObject);
    }
}

public class AnotherClass<T> where T : bar
{
    public void testMethod(foo<T> dummy)
    {
        foobar = dummy;
    }

    private foo<T> foobar = null;
}

public class foo<T> where T : bar, new()
{
    public foo()
    {
        _t = new T();
    }

    private T _t;

}

public abstract class bar
{
    public abstract void someMethod();
    // Some implementation
}

public class baz : bar
{
    public override void someMethod()
    {
        //Implementation
    }
}    

Und ich erhalte eine Fehlermeldung, die besagt, dass "T" ein nicht-abstrakter Typ mit einem öffentlichen parameterlosen Konstruktor sein muss, um ihn als Parameter "T" im generischen Typ oder in der generischen Methode verwenden zu können. Ich verstehe vollkommen, warum das so sein muss, und ich verstehe auch, dass ich ein vorinitialisiertes Objekt vom Typ "T" als Konstruktorargument übergeben könnte, um zu vermeiden, dass ich es "neu" erstellen muss, aber gibt es eine Möglichkeit, dies zu umgehen? Gibt es eine Möglichkeit, Klassen, die von "bar" abgeleitet sind, dazu zu zwingen, parameterlose Konstruktoren bereitzustellen?

Festgelegt - Mir fehlte eine 'new()'-Beschränkung für AnotherClass().

7voto

Gerrie Schenck Punkte 21800

Die korrekte Syntax lautet

public class foo<T> where T : bar, new()

5voto

Ian Mercer Punkte 37031

Fehlt Ihnen nicht eine new()-Beschränkung für Ihre AnotherClass?

public class AnotherClass<T> where T : bar, new()

Ohne diese weigert sich VS2010 zu kompilieren, mit dieser funktioniert es ganz gut.

1voto

devio Punkte 36064

Ihr Code kompiliert in VS2010.

Wahrscheinlich sollten Sie stattdessen Schnittstellen verwenden:

public class foo<T> where T : ibar, new()
...

public interface ibar
{
    void someMethod();
}

public abstract class bar : ibar
{
    public abstract void someMethod();
    // Some implementation
}

0voto

Ist die generische Syntax nicht new() und nicht nur new?

Außerdem führen Sie diesen Code in der Mitte einer Klasse und nicht in einer Funktion aus, was ihn sicher verwirren wird:

_t = new T();

Editar:

Ok, also nach der Syntaxbereinigung vermute ich, dass das Problem darin besteht, dass "baz" keinen parameterlosen Konstruktor hat. Ich kenne keinen Weg, wie man das erzwingen kann.

Es gibt eine ähnliche Frage aquí die vielleicht ein wenig weiterhelfen.

0voto

Andrew Bezzub Punkte 15286

Wie Abhilfe - Sie können Delegate übergeben, die die Instanz eines Typs erstellen, den Sie benötigen:

  Func<T> creator = ...

  _t = creator();

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