Pergunta

Isto não é legal:

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


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

A fim de fazer isso, você tem que fazer alguma reflexão sobre o objeto tipo para T ou você tem que usar Activator.CreateInstance. Ambos são bastante desagradável. Existe uma maneira melhor?

Foi útil?

Solução

Você não pode restringir T ter uma assinatura de construtor especial que não seja um construtor vazio, mas você pode restringir T ter um método de fábrica com a assinatura desejada:

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

No entanto, gostaria de sugerir talvez usando um padrão criacional diferente, como o Abstract Factory para este cenário.

Outras dicas

Não. Se você não estivesse passando em parâmetros, então você pode restringir o seu tipo de param de exigir um construtor sem parâmetros. Mas, se você precisa passar argumentos que você está fora de sorte.

where T : MyBaseClass, new()

só funciona w / parâmetros construtor público. além disso, de volta para Activator.CreateInstance (que realmente não é tão ruim).

Eu posso ver que não funciona.

Mas o que é que você parar de fazer isso?

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

Uma vez que tudo está indo para herdar de MyBaseClass eles vão al ser MyBaseClass, certo?

Eu tentei e isso funciona.

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!");
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top