Frage

Dies ist nicht zulässig:

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


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

Um dies zu tun, müssen Sie für T eine Reflexion über die Art Objekt tun, oder Sie haben Activator.CreateInstance zu verwenden. Beide sind ziemlich böse. Gibt es einen besseren Weg?

War es hilfreich?

Lösung

Sie können nicht T einschränken eine bestimmte Konstruktor Unterschrift andere als ein leerer Konstruktor haben, aber Sie können T einschränken mit der gewünschten Signatur eine Factory-Methode haben:

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

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

Allerdings würde ich vorschlagen, vielleicht ein anderen Erzeugungsmuster wie Abstract Factory für dieses Szenario verwendet wird.

Andere Tipps

Nein. Wenn Sie nicht in Parameter übergeben wurden, dann könnten Sie Ihren Typ param beschränken, um einen parameterlosen Konstruktor benötigen. Aber, wenn Sie Argumente brauchen, sind aus Glück Sie weiter.

where T : MyBaseClass, new()

funktioniert nur w / parameterlos öffentlichen Konstruktor. darüber hinaus, zurück zu Activator.CreateInstance (was wirklich nicht so schlimm ist).

Ich kann sehen, dass nicht funktioniert.

Aber was halten Sie davon ab dies zu tun?

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

Da alles von MyBaseClass erben wird sie al seinen MyBaseClass, nicht wahr?

Ich versuchte es 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<MyClass>();
            ThisIsANoNo<MyBaseClass>();
        }

        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<T>() where T : MyBaseClass
        {
            MyBaseClass foo = new MyBaseClass("whoops!");
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top