Mewarisi dari kelas dasar generik, menerapkan batasan, dan menerapkan antarmuka di C #

117

Ini adalah pertanyaan sintaks. Saya memiliki kelas generik yang mewarisi dari kelas dasar generik dan menerapkan batasan ke salah satu parameter tipe. Saya juga ingin kelas turunan untuk mengimplementasikan antarmuka. Untuk kehidupan saya, saya tidak bisa menemukan sintaks yang benar.

Inilah yang saya miliki:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

Hal pertama yang terlintas dalam pikiran adalah ini:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Tapi itu tidak benar karena itu menyebabkan T2 perlu mengimplementasikan IBar dan IFoo, bukan DerivedFoo untuk mengimplementasikan IFoo.

Saya sudah mencoba sedikit Googling, penggunaan titik dua, titik koma, dll, tapi ternyata saya kekurangan. Saya yakin jawabannya sederhana saja.

Dan Rigby
sumber
Saya tidak dapat memahami jawaban @ Adam ketika saya melihat sekali tetapi setelah 2 menit saya bisa mendapatkan apa adanya, terima kasih atas jawabannya. Kelas turunan memiliki lebih dari satu implementasi mungkin ini intinya. Pokoknya saya ingin menunjukkan notasinya untuk orang lain. "class DerivedClass <Type>: ParentClass di mana Type: IType". Tidak ada yang harus antara kelas yang terakhir diimplementasikan dan klausa where.
nurisezgin

Jawaban:

173

Anda menyertakan seluruh tanda tangan kelas Anda sebelum Anda menentukan batasan umum.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}
Adam Robinson
sumber
5
Kepada orang lain, saya telah menginternalisasi ini sebagai, kelas hanya mendapat satu klausa where, dan itu berjalan di akhir untuk semua & semua batasan tipe generik.
Andy V
@Visser Diperbolehkan untuk memiliki beberapa klausa mana, kelas Tes <T1, T2> di mana T1: Antarmuka1 di mana T2: Antarmuka2
bwing
@Visser ya, apa yang dikatakan bwing, juga masing-masing klausa dapat memiliki beberapa batasan… jadi sintaks dari posting asli benar, itu hanya berarti sesuatu yang berbeda yang diinginkan op. where T2 : IBar, IFoo hanya berarti T2harus mengimplementasikan kedua antarmuka alih-alih DerivedFoo<T1,T2> menerapkanIFoo
v01pe
18

Rekomendasi saya: ketika Anda memiliki pertanyaan tentang sintaks bahasa C #, baca spesifikasinya; itulah mengapa kami mempublikasikannya. Anda pasti ingin membaca bagian 10.1.

Untuk menjawab pertanyaan spesifik Anda, urutan hal-hal dalam deklarasi kelas adalah:

  • atribut, dalam tanda kurung siku
  • pengubah ("publik", "statis", dan sebagainya)
  • "sebagian"
  • "kelas"
  • nama kelas
  • daftar deklarasi parameter tipe yang dipisahkan koma di dalam tanda kurung sudut
  • titik dua diikuti daftar jenis dasar yang dipisahkan koma (kelas dasar dan antarmuka yang diimplementasikan, kelas dasar harus ditempatkan terlebih dahulu jika ada)
  • jenis batasan parameter
  • tubuh kelas, dikelilingi oleh kawat gigi
  • titik koma

Semua yang ada di daftar itu opsional kecuali untuk "kelas", nama, dan isi, tetapi semuanya harus muncul dalam urutan itu jika muncul.

Eric Lippert
sumber
95
Eric, sementara saya sangat menghormati Anda sebagai seorang profesional dan menghargai umpan balik Anda, saya tidak dapat membantu tetapi menjadi frustrasi dengan apa yang muncul sebagai jawaban kasar. Anda mengkritik saya karena memilih untuk mengajukan pertanyaan pada situs Q&A pemrograman daripada mencari, mengunduh, dan mencari melalui halaman dokumen Word 503 yang sangat teknis yang terkubur dari tautan di MSDN. Itu cukup kasar. Ini adalah penggunaan waktu saya yang paling efisien dan memiliki manfaat tambahan yang dapat membantu orang lain di kemudian hari. Tautan ke C # Lang Spec bagi mereka yang tertarik adalah: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Dan Rigby
17
Tidak ada kritik yang dimaksudkan. Ada bias yang meluas dalam komunikasi teks murni yang membuat pernyataan fakta sederhana terdengar kasar dan kasar; Saya mencoba membaca dengan ramah ketika disajikan dengan daftar fakta bermanfaat, dan menyarankan Anda untuk melakukannya juga. Saya mendukung rekomendasi saya; jika Anda memiliki pertanyaan tentang sintaks, spesifikasi menjawabnya dengan pasti dan dimulai dengan daftar isi yang berguna untuk menemukan definisi sintaks tertentu.
Eric Lippert
3
Dan, menemukan spesifikasi C # semudah memasukkan 'C # Spec' di Google dan menekan tombol 'Saya beruntung'. Dan jika Anda adalah pengembang C # profesional, Anda seharusnya sudah memiliki spesifikasi C # dalam format PDF di komputer Anda. Juga, saya juga tidak bermaksud mengkritik Anda. Saya tidak terbiasa membaca spec sebelumnya tetapi saya sudah mulai membacanya berkat Jon, Eric dan Pavel yang selalu mengutip spesifikasi C # untuk setiap pertanyaan. Saya menemukan bahwa spesifikasi C #, meskipun terkadang sulit dibaca, adalah cara yang bagus untuk belajar tentang bahasa tersebut.
SolutionYogi
@ Eric Lipt: Cukup adil. Terimakasih atas balasan anda. Sebagai saran yang membangun, akan sangat membantu jika Microsoft akan mengintegrasikan konten spesifikasi secara langsung ke MSDN sebagai tambahan untuk membuatnya ada sebagai unduhan terpisah. Versi Visual Studio .Net MSDN memiliki versi terintegrasi dari spesifikasi, tetapi bukan versi yang lebih baru. Saya telah memikirkan untuk membeli buku Anders Hejlberg, tetapi dengan .Net 4.0 sudah dekat saya enggan melakukannya. amazon.com/C-Programming-Language-3rd/dp/0321562992 Terima kasih.
Dan Rigby
2
C ++ mengharuskan deklarasi kelas diakhiri dengan titik koma. Banyak pengembang C # berasal dari latar belakang C ++; terkadang jari-jari mereka meletakkan titik koma tanpa melibatkan otak mereka. :-) Ada sejumlah konstruksi di C # yang mengambil semi opsional di mana C ++ memerlukannya. Ini hanya kenyamanan yang halus. Saya kira itu juga memungkinkan Anda secara halus memanggil ketika deklarasi tipe berakhir vs mengatakan deklarasi tubuh metode.
Eric Lippert
8
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }
Stan R.
sumber
2
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Ini adalah perpanjangan dari jawaban yang ada. Ini defaultnya stringjika Anda tidak memberikan tipe. Saya tidak menerapkan antarmuka tetapi itu seharusnya tidak memerlukan sesuatu yang berbeda dari biasanya.

pengguna875234
sumber