Bagaimana saya bisa memberi contoh tipe T di dalam InstantiateType<T>
metode saya di bawah ini?
Saya mendapatkan kesalahan: 'T' adalah 'parameter tipe' tetapi digunakan seperti 'variabel'. :
(GULIR KE BAWAH UNTUK JAWABAN DEFAKTORKAN)
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; }
}
}
JAWABAN YANG DITERBITKAN:
Terima kasih atas semua komentarnya, mereka membuat saya di jalur yang benar, inilah yang ingin saya lakukan:
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; }
}
}
Jawaban:
Nyatakan metode Anda seperti ini:
Perhatikan kendala tambahan di bagian akhir. Kemudian buat sebuah
new
instance di dalam metode body:sumber
Beberapa cara.
Tanpa menentukan tipe harus memiliki konstruktor:
Dengan konstruktor:
Tapi ini membutuhkan klausul:
sumber
Untuk memperluas jawaban di atas, menambahkan
where T:new()
batasan ke metode umum akan membutuhkan T untuk memiliki konstruktor publik tanpa parameter.Jika Anda ingin menghindarinya - dan dalam pola pabrik terkadang Anda memaksa yang lain untuk menggunakan metode pabrik Anda dan tidak secara langsung melalui konstruktor - maka alternatifnya adalah menggunakan refleksi (
Activator.CreateInstance...
) dan menjaga agar konstruktor default tetap pribadi. Tapi ini datang dengan penalti performa, tentu saja.sumber
Anda ingin baru T (), tetapi Anda juga harus menambahkan
, new()
kewhere
spec untuk metode pabriksumber
Agak tua tetapi untuk orang lain yang mencari solusi, mungkin ini bisa menarik: http://daniel.wertheim.se/2011/12/29/c-generic-factory-with-support-for-private-constructors/
Dua solusi. Satu menggunakan Activator dan satu lagi menggunakan Compiled Lambdas.
sumber
Anda juga dapat menggunakan refleksi untuk mengambil konstruktor objek dan membuat instance seperti itu:
sumber
Menggunakan kelas pabrik untuk membangun objek Anda dengan ekspresi lamba terkompilasi: Cara tercepat yang saya temukan untuk membuat instance tipe generik.
Berikut adalah langkah-langkah yang saya ikuti untuk menyiapkan patokan.
Buat metode pengujian benchmark saya:
Saya juga mencoba menggunakan metode pabrik:
Untuk tes saya telah membuat kelas paling sederhana:
Script yang akan diuji:
Catatan : Saya telah menguji menggunakan .NET Framework 4.5 dan 4.6 (hasil yang setara).
sumber
Alih-alih membuat fungsi untuk membuat instance tipe
Anda bisa melakukannya seperti ini
sumber
new()
kendala masih diperlukan pada jenis generik untuk jawaban Anda bekerja.