Genel bir temel sınıftan devralın, bir kısıtlama uygulayın ve C # 'da bir arabirim uygulayın


117

Bu bir söz dizimi sorusudur. Genel bir temel sınıftan miras alan ve tür parametrelerinden birine bir kısıtlama uygulayan genel bir sınıfım var. Ayrıca türetilmiş sınıfın bir arabirim uygulamasını istiyorum. Hayatım boyunca, doğru sözdizimini bulamıyorum.

Sahip olduğum şey bu:

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

Akla gelen ilk şey şuydu:

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

Ancak bu yanlıştır çünkü T2'nin IFoo'yu uygulamak için DerivedFoo'yu değil, hem IBar'ı hem de IFoo'yu uygulaması gerekir.

Biraz Google'ı denedim, iki nokta üst üste, noktalı virgül vb. Kullanmayı denedim, ancak kısa sonuç verdim. Eminim cevap çok basittir.


@ Adam'ın cevabını bir kez baktığımda anlayamadım ama 2 dakika sonra ne olduğunu anlayabildim, cevabın için teşekkürler. Türetilmiş sınıf birden fazla uygulamaya sahiptir, mesele bu olabilir. Her neyse, başkaları için notasyonunu göstermek istiyorum. "Class DerivedClass <Type>: ParentClass burada Type: IType". Son uygulanan sınıf ile where cümlesi arasında hiçbir şey olmamalıdır.
nurisezgin

Yanıtlar:


173

Genel kısıtlamaları tanımlamadan önce sınıfınızın tüm imzasını dahil edersiniz.

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

5
Diğerlerine göre, bunu bir sınıfın yalnızca bir where cümlesi alır ve her tür ve tüm genel tip kısıtlamaları için sonunda gittiğini içselleştirdim.
Andy V

@Visser Birden fazla where cümlesi olmasına izin verilir, sınıf Test <T1, T2> burada T1:
Arayüz1

@Visser evet, bwing ne dedi, ayrıca her bir cümlenin birden fazla kısıtlaması olabilir… yani orijinal gönderideki sözdizimi doğru, sadece operasyonun istediği farklı bir şey anlamına geliyor. where T2 : IBar, IFoo Sadece araç T2yerine her iki arabirimleri uygulamak zorundadır DerivedFoo<T1,T2> uygulanmasıIFoo
v01pe

18

Benim tavsiyem: C # dilinin sözdizimi hakkında bir sorunuz olduğunda, spesifikasyonu okuyun; bu yüzden yayınlıyoruz. Bölüm 10.1'i okumak isteyeceksiniz.

Özel sorunuzu yanıtlamak için, bir sınıf bildirimindeki şeylerin sırası şöyledir:

  • öznitelikler, köşeli parantez içinde
  • değiştiriciler ("genel", "statik" vb.)
  • "kısmi"
  • "sınıf"
  • sınıf adı
  • açılı ayraçlar içinde tür parametresi bildirimlerinin virgülle ayrılmış listesi
  • iki nokta üst üste, virgülle ayrılmış temel türler listesini takip eder (temel sınıf ve uygulanan arabirimler, varsa temel sınıf önce gelmelidir)
  • tür parametresi kısıtlamaları
  • parantezlerle çevrili sınıfın gövdesi
  • noktalı virgül

Bu listedeki "sınıf", ad ve gövde dışında her şey isteğe bağlıdır, ancak görünürse her şey bu sırayla görünmelidir.


95
Eric, bir profesyonel olarak sana büyük saygı duyuyor ve geri bildirimini takdir ediyor olsam da, yardım edemem ama aşındırıcı bir cevap olarak karşımıza çıkan şey beni hayal kırıklığına uğratıyor. MSDN'deki bir bağlantıda gömülü oldukça teknik bir 503 sayfalık Word belgesini bulmak, indirmek ve aramak yerine programlama Soru-Cevap sitesinde soru sormayı seçtiğim için beni eleştiriyorsunuz. Bu oldukça sert. Bu, zamanımın en verimli kullanımıydı ve daha sonra başka birine yardımcı olabileceği gibi ek bir faydası da var. İlgilenenler için C # Lang Spec'in bağlantısı: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Dan Rigby

17
Eleştiri amaçlanmadı. Saf metin iletişiminde yaygın bir önyargı vardır, bu da gerçeklerle ilgili basit ifadeleri kaba ve aşındırıcı kılar; Yararlı gerçeklerin bir listesi sunulduğunda yardımsever bir şekilde okumaya çalışıyorum ve sizin de yapmanızı tavsiye ediyorum. Ben tavsiyemin arkasında duruyorum; sözdizimi hakkında sorularınız varsa, belirtim bunları kesin bir şekilde yanıtlar ve belirli sözdizimlerinin tanımlarını bulmak için yardımcı bir içindekiler tablosu ile başlar.
Eric Lippert

3
Dan, C # spesifikasyonunu bulmak Google'da 'C # Spesifikasyonunu' girip 'şanslıyım' düğmesine basmak kadar basit. Ve profesyonel bir C # geliştiriciyseniz, makinenizde halihazırda PDF formatında C # spesifikasyonuna sahip olmalısınız. Ayrıca seni eleştirmek de istemiyorum. Daha önce spesifikasyonları okumaya alışkın değildim ama her soru için C # spesifikasyonundan alıntı yapan Jon, Eric ve Pavel sayesinde okumaya başladım. C # spesifikasyonunun, bazen okunması zor olsa da, dili öğrenmek için harika bir yol olduğunu buldum.
SolutionYogi

@Eric Lippert: Yeterince adil. Cevabın için teşekkürler. Yapıcı bir öneri olarak, Microsoft'un spesifikasyonun içeriğini ayrı bir indirme olarak bulunmasına ek olarak doğrudan MSDN'ye entegre etmesi yararlı olacaktır. Visual Studio .Net MSDN sürümü, belirtimin tümleşik bir sürümüne sahiptir, ancak sonraki sürümleri yoktur. Anders Hejlberg'in kitabını satın almayı düşündüm, ancak köşede .Net 4.0 ile henüz isteksizim. amazon.com/C-Programming-Language-3rd/dp/0321562992 Teşekkürler.
Dan Rigby

2
C ++ , bir sınıf bildiriminin noktalı virgülle bitmesini gerektirir . Çoğu C # geliştiricisi C ++ arka planından gelir; bazen parmakları beyinleri karışmadan noktalı virgül koyarlar. :-) C # 'da, C ++' nın bir tane gerektirdiği isteğe bağlı bir yarı alan bir dizi yapı vardır. Bu hemen hemen sadece ince bir rahatlık. Sanırım aynı zamanda bir tür bildirimi sona erdiğinde, bir yöntem gövdesi bildirimi diyelim.
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 { }

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

Bu, mevcut cevapların bir uzantısıdır. stringBir tür sağlamazsanız varsayılan olarak ayarlanır . Bir arayüz uygulamadım ama bu normalden farklı bir şey gerektirmemeli.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.