Gibt es eine elegante Möglichkeit, einen variablen Typ mit Parametern zu instanziieren?

Dies ist nicht legal:

public class MyBaseClass
{
  public MyBaseClass() {}
  public MyBaseClass(object arg) {}
}


public void ThisIsANoNo() where T : MyBaseClass
{
  T foo = new T("whoops!");
}

Um dies zu tun, müssen Sie etwas über das Typobjekt für T nachdenken, oder Sie müssen Activator.CreateInstance verwenden. Beide sind ziemlich böse. Gibt es einen besseren Weg?

0

4 Antworten

where T : MyBaseClass, new()

funktioniert nur mit parameterlosem öffentlichen Konstruktor. darüber hinaus zurück zu activator.CreateInstance (was wirklich nicht so schlimm ist).

0
hinzugefügt
nicht auf generische Weise.
hinzugefügt der Autor Darren Kopp, Quelle

Ich kann sehen, dass das nicht funktioniert.

Aber was hält dich davon ab?

public void ThisIsANoNo() where T : MyBaseClass
{
  MyBaseClass foo = new MyBaseClass("whoops!");
}

Da alles von MyBaseClass erben wird, wird es MyBaseClass sein, oder?

Ich habe es versucht und das funktioniert.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ThisIsANoNo();
            ThisIsANoNo();
        }

        public class MyBaseClass
        {
            public MyBaseClass() { }
            public MyBaseClass(object arg) { }
        }

        public class MyClass :MyBaseClass
        {
            public MyClass() { }
            public MyClass(object arg, Object arg2) { }
        }

        public static void ThisIsANoNo() where T : MyBaseClass
        {
            MyBaseClass foo = new MyBaseClass("whoops!");
        }
    }
}
0
hinzugefügt
T ist eine Erweiterung von MyBaseClass. Sie können eine Instanz von MyBaseClass neu erstellen, aber Sie können sie nicht nach T hochtransformieren, weil es kein T ist. Darüber hinaus erstellt Ihre ThisIsANoNo-Implementierung, während sie eine generische Signatur hat, keine Instanz von Typ Variable.
hinzugefügt der Autor Will, Quelle
Es ist eine Leere, es bringt nichts zurück. und eine Besetzung kann das beheben.
hinzugefügt der Autor chrissie1, Quelle
@Abe ich habe es ausprobiert und es funktioniert.
hinzugefügt der Autor chrissie1, Quelle
Was passiert, wenn Sie eine abgeleitete Klasse haben, die nur einen Konstruktor mit 2 Argumenten hat?
hinzugefügt der Autor Abe Heidebrecht, Quelle
Diese Methode gibt niemals Objekte vom Typ T zurück, sondern nur Objekte vom Typ MyBaseClass.
hinzugefügt der Autor Matt Howells, Quelle

Nee. Wenn Sie keine Parameter übergeben, können Sie Ihren Typ-Parameter darauf beschränken, einen parameterlosen Konstruktor zu benötigen. Aber wenn Sie Argumente weitergeben müssen, haben Sie kein Glück.

0
hinzugefügt

Sie können nicht festlegen, dass T eine bestimmte Konstruktorsignatur hat, außer einem leeren Konstruktor. Sie können jedoch festlegen, dass T eine Factory-Methode mit der gewünschten Signatur verwendet:

public abstract class MyBaseClass
{
    protected MyBaseClass() {}
    protected abstract MyBaseClass CreateFromObject(object arg);
}

public void ThisWorksButIsntGreat() where T : MyBaseClass, new()
{
    T foo = new T().CreateFromObject("whoopee!") as T;
}

Ich würde jedoch vorschlagen, für dieses Szenario vielleicht ein anderes Kreationsmuster wie Abstract Factory zu verwenden.

0
hinzugefügt