Как я могу создать экземпляр типа T внутри моего InstantiateType<T>
метода ниже?
Я получаю сообщение об ошибке: «T» - это «параметр типа», но используется как «переменная». :
(ПРОКРУТИТЕ ВНИЗ, ЧТОБЫ ОТВЕЧИТЬ ОТВЕТ)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGeneric33
{
class Program
{
static void Main(string[] args)
{
Container container = new Container();
Console.WriteLine(container.InstantiateType<Customer>("Jim", "Smith"));
Console.WriteLine(container.InstantiateType<Employee>("Joe", "Thompson"));
Console.ReadLine();
}
}
public class Container
{
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson
{
T obj = T();
obj.FirstName(firstName);
obj.LastName(lastName);
return obj;
}
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public class Customer : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
}
public class Employee : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeNumber { get; set; }
}
}
ПЕРЕФАКТОРНЫЙ ОТВЕТ:
Спасибо за все комментарии, они наставили меня на верный путь, вот что я хотел сделать:
using System;
namespace TestGeneric33
{
class Program
{
static void Main(string[] args)
{
Container container = new Container();
Customer customer1 = container.InstantiateType<Customer>("Jim", "Smith");
Employee employee1 = container.InstantiateType<Employee>("Joe", "Thompson");
Console.WriteLine(PersonDisplayer.SimpleDisplay(customer1));
Console.WriteLine(PersonDisplayer.SimpleDisplay(employee1));
Console.ReadLine();
}
}
public class Container
{
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson, new()
{
T obj = new T();
obj.FirstName = firstName;
obj.LastName = lastName;
return obj;
}
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public class PersonDisplayer
{
private IPerson _person;
public PersonDisplayer(IPerson person)
{
_person = person;
}
public string SimpleDisplay()
{
return String.Format("{1}, {0}", _person.FirstName, _person.LastName);
}
public static string SimpleDisplay(IPerson person)
{
PersonDisplayer personDisplayer = new PersonDisplayer(person);
return personDisplayer.SimpleDisplay();
}
}
public class Customer : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
}
public class Employee : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeNumber { get; set; }
}
}
Ответы:
Объявите свой метод следующим образом:
Обратите внимание на дополнительное ограничение в конце. Затем создайте
new
экземпляр в теле метода:источник
Пара способов.
Без указания типа обязательно иметь конструктор:
С конструктором:
Но для этого требуется пункт:
источник
Чтобы расширить ответы выше, добавление
where T:new()
ограничения к универсальному методу потребует, чтобы у T был общедоступный конструктор без параметров.Если вы хотите избежать этого - а в шаблоне фабрики вы иногда заставляете других проходить через ваш фабричный метод, а не напрямую через конструктор - тогда альтернативой является использование Reflection (
Activator.CreateInstance...
) и сохранение конструктора по умолчанию закрытым. Но это, конечно, приводит к снижению производительности.источник
вам нужен новый T (), но вам также необходимо добавить
, new()
вwhere
спецификацию для заводского методаисточник
Немного устарел, но для других, которые ищут решение, возможно, это может быть интересно: http://daniel.wertheim.se/2011/12/29/c-generic-factory-with-support-for-private-constructors/
Два решения. Один использует Activator, а другой - скомпилированные лямбды.
источник
Вы также можете использовать отражение, чтобы получить конструктор объекта и создать его таким образом:
источник
Использование фабричного класса для создания вашего объекта с помощью скомпилированного лямб-выражения: самый быстрый способ, который я нашел, для создания экземпляра универсального типа.
Вот шаги, которые я выполнил для настройки теста.
Создайте свой метод тестирования производительности:
Я также пробовал использовать заводской метод:
Для тестов я создал простейший класс:
Скрипт для тестирования:
Примечания : Я тестировал как .NET Framework 4.5, так и 4.6 (эквивалентные результаты).
источник
Вместо создания функции для создания экземпляра типа
ты мог бы сделать это вот так
источник
new()
Ограничение по - прежнему необходимо на общем типе для вашего ответа на работу.