2012-01-13 17 views
21

Bunun için bana hem ItemA'nın hem de ItemB'nin adını söylemesini istiyorum. Bana "Subitem \ nSubitem" demeli, bunun yerine "Item \ nSubitem" yazıyor. Bunun nedeni, Subitem sınıfında tanımlanan "Ad" değişkeninin teknik olarak, Temel Öğe sınıfında tanımlanan "Ad" değişkeninden farklı bir değişkendir. Orijinal değişkeni yeni bir değere değiştirmek istiyorum. Bunun neden en kolay şey olduğunu anlayamıyorum, sanal olarak düşünmek ve yöntemleri mükemmel bir şekilde geçersiz kılmak. 'un aslında bir değişkeni nasıl geçersiz kıldığını öğrenemedim. alanlara (bir değişkenleri dediğimiz) ile (override onun şey kılan) polimorfizm hiçbir kavram yokturC# alt sınıfında bir üye değişkeni (alan) nasıl geçersiz kılar, gizlerim?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Example 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      System.Console.WriteLine(ItemA.Name); 
      System.Console.WriteLine(ItemB.Name); 
      System.Console.ReadKey(); 
     } 
     static Item ItemA = new Subitem(); 
     static Subitem ItemB = new Subitem(); 
    } 
    public class Item 
    { 
     public string Name = "Item"; 
    } 
    public class Subitem : Item 
    { 
     new public string Name = "Subitem"; 
    } 
} 
+1

Sen * sanal * olabilir şeye ihtiyacım - a * Mülkiyet * ("Getter") veya * Yöntemi *. Üye değişkenler * asla * sanal değildir. –

cevap

29

yapamazsınız geçersiz kılma C# değişkenler, ancak özellikleri değiştirebilirim:

public class Item 
{ 
    public virtual string Name {get; protected set;} 
} 
public class Subitem : Item 
{ 
    public override string Name {get; protected set;} 
} 

başka bir yaklaşım bu gibi alt sınıfta değerini değiştirmek için olurdu:

public class Item 
{ 
    public string Name = "Item"; 
} 
public class Subitem : Item 
{ 
    public Subitem() 
    { 
     Name = "Subitem"; 
    } 
} 
+1

@ Eagle-Eye Polimorfik değişkenler ne yapar? Teoriyi açıklayamazsanız, uygulamayı eleştirmeyin. –

+0

+1, Jon, @ Eagle-Eye. Polimorfizm, türetilmiş türlerde * işlevsellik * ile ilgili olduğu düşünüldüğünde, (işlevsellik içermeyen) alanlar gibi bir şeye uygulanması mantıklı değildir. –

+0

@Jon Yorumumu tekrar okuduğumda söylemek biraz aptaldı. Gerçekten kastettiğim şey, bir alt sınıftaki bir değişkenin varsayılan değerini kurucunun içinde yapamayacağımı (keşke nasıl yapıldığına dair bir betik dilinden geldiğimden) istediğimdi. Bunu daha önce ifade etmede zayıf bir iş yaptım. Bununla birlikte, "teoriyi açıklayamıyorsanız uygulamayı eleştirmeyin" bile ne anlama geliyor? "Diğer yöntemler aptalca ve utangaç görünüyor" olduğu sürece, ayrı bir varsayılan değere sahip olmak için bir get metodu yapmamı kastediyordum. (Ancak, aptal kelimesinin kullanılmasından pişmanım.) –

8

. Burada kullanmanız gereken şey bir özelliktir.

public class Item 
{ 
    public virtual string Name 
    { 
     get { return "Item"; } 
    } 
} 

public class SubItem : Item 
{ 
    public override string Name 
    { 
     get { return "Subitem"; } 
    } 
} 
+1

Muhtemelen bu gibi değerleri kodlayamasa da, değişebilir. –

+0

Kesinlikle doğru. Bir "sanal değişken" anlamsızdır. Java tarzı "getter()" ve "setter()" yöntemlerinin neden bu kadar kullanışlı olmasının büyük bir kısmı.Ve C# "mülk" (Delphi'nin zaten çok iyi olan "özelliklerinden bir avans") kavramı, alıcı/ayarlayıcı yöntemlere olan ihtiyacın çoğunu ortadan kaldırır. "Özellikler" kesinlikle bu sorunun cevabıdır. Ayrıca bu konuya bakın: http://stackoverflow.com/questions/1112458/c-sharp-member-variable-overrides-used-by-base-class-method – paulsm4

+1

@JeffMercado: Doğru olsa da, sıkı bir şekilde yapmaya çalışıyordum. OP'nin sorusunun orijinal biçimine, bahsettiğim farklılığı göstermek için (özellikler vs. alanlar). –

0

Olası bir çözüm, bir özelliği kullanmak ve alıcısını geçersiz kılmak, örneğin:

public class Item 
{ 
    public virtual string Name { get { return "Item"; } } 
} 
public class Subitem : Item 
{ 
    public override string Name { get { return "Subitem"; } } 
} 
+1

Bu, daha sonra değerin değiştirilmesini engeller. – x3ro

4

"Bir değişkeni geçersiz kılmak" ne anlama gelir?

Bir değişken, kavramsal bellekte adlandırılmış bir konumdur ("kavramsal", çünkü bir kayıt olabilir, ancak alanlarla ilgili olmasa da).

Bir yöntemin geçersiz kılınması, başka bir işlemin yerine geçer.

Bellekteki bir adlandırılmış konum bir işlem kümesi olmadığından, bunların yerini nasıl alırsınız? Bu adlandırılmış konumun bellekte kullanılmasını bekleyen şeyler nelerdir? Eğer operasyonların set olarak geçersiz kılmak isterseniz, o zaman operasyonların bir dizi tanımlamak

public class Item 
{ 
    public string Name = "Item"; 
} 
public class Subitem : Item 
{ 
    public SubItem() 
    { 
    Name = "Subitem"; 
    } 
} 

:

sonra sadece türetilmiş sınıf inşa edildiğinde bunu, hafızada saklanır neyi değiştirmek istiyorsanız

(bir yöntem veya özellik) geçersiz kılmak için.

1

Bu soru nispeten eski ve yazar muhtemelen C# 5.0 veya daha düşük kullanıyordu. Ama ben aynı soruyu vardı ve C# 6.0 ile çalıştığı ve sizinle paylaşmak istediğim daha yüksek bir çözümle karşılaştım:

C# 6.0, otomatik özelliklerin başlatılmasını sağlar. Yani bir sadece kullanabilirsiniz:

public class Item 
{ 
    public virtual string Name { get; set; } = "Item"; 
} 

public class Subitem : Item 
{ 
    public override string Name { get; set; } = "Subitem"; 
} 
İlgili konular