Domanda

Questo non è legale:

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


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

Per fare ciò, devi fare qualche riflessione sul tipo oggetto per T oppure devi usare Activator.CreateInstance.Entrambi sono piuttosto cattivi.C'è un modo migliore?

È stato utile?

Soluzione

Non puoi vincolare T ad avere una particolare firma del costruttore diversa da un costruttore vuoto, ma puoi vincolare T ad avere un metodo factory con la firma desiderata:

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;
}

Tuttavia, suggerirei forse di utilizzare un modello creativo diverso come Abstract Factory per questo scenario.

Altri suggerimenti

No.Se non stavi passando parametri, potresti vincolare il tuo tipo param per richiedere un costruttore senza parametri.Ma se hai bisogno di discutere, sei sfortunato.

where T : MyBaseClass, new()

funziona solo con un costruttore pubblico senza parametri.oltre a ciò, torniamo a activator.CreateInstance (che in realtà non è poi così male).

Vedo che non funziona.

Ma cosa ti impedisce di farlo?

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

Dato che tutto erediterà da MyBaseClass, saranno tutti MyBaseClass, giusto?

L'ho provato e funziona.

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!");
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top