我的大腦會爆炸。 :)所以我想從你那裏得到幫助。 請考慮一下我的問題,例如關於程序員謎題。 (其實,也許這對你來說是很容易的問題,但不適合我)。繼承泛型類C#
需要創建對象數組。例如列表,其中T是類。 (我將在下面描述T類)。此外,它需要創建「容器」,將包含此數組和一些方法來處理這個數組。例如Add(),Remove(int IndexToRemove)。 類T必須有字段「容器」,這樣我們數組中的每個元素都能夠知道它包含的內容並訪問其容器的字段和方法。注意,在這種情況下,類T應該有類型參數。事實上,事先並不知道使用哪種容器的類型。 讓我們將這個類容器表示爲A,將類元素(類T)表示爲AUnit。
代碼:
class Program
{
static void Main(string[] args)
{
A a = new A();
a.Add();
a.Units[0].SomeField +=100;
Console.ReadKey();
}
}
class A
{
public List<AUnit> Units;
public A()//ctor
{
Units = new List<AUnit>();
}
public void Add()
{
this.Units.Add(new AUnit(this));
}
}
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
}
公共領域應受到保護或私人的課程,但後來我們想想這一點。 您可以問「爲什麼我們在AUnit中創建公共A容器字段」?我們創建字段公共字符串名稱{獲取;私人設置;}(實際上屬性,但從來沒有)。我們還希望能夠更改此字段的值,例如方法[Class AUnit] public bool Rename(string newName)();.這種方法的主要思想是隻有在數組(公共列表單位;)中沒有一個元素具有相同名稱(如newName)的情況下才更改名稱字段。但要實現這一點,Rename方法必須能夠訪問當前使用的所有名稱。這就是爲什麼我們需要Container領域。
的擴展版本代碼AUnit
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (AUnit unt in this.Container.Units)
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
確定。如果你仍然閱讀它,讓我們繼續。現在我們需要創建類B和類BUnit,它們與A類和Aunit類非常相似。最後,這個難題的主要問題是我們如何做到這一點?當然,我可以CopyPaste和位修改A和AUnit並創建此代碼。
class B
{
public List<BUnit> Units; //Only Type Changing
public B()//ctor Name changing...
{
Units = new List<BUnit>();//Only Type Changing
}
public void Add()
{
this.Units.Add(new BUnit(this));//Only Type Changing
}
}
class BUnit
{
public int SomeField;
public B Container;//Only Type Changing
public string Name { get; private set; }
public A a; //NEW FIELD IS ADDED (just one)
public BUnit(B container) //Ctor Name and arguments type changing
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
this.a=new A(); //New ROW (just one)
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (BUnit unt in this.Container.Units) //Only Type Changing
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
我可以通過這種方式使用這個類。
static void Main(string[] args)
{
B b = new B();
b.Add();
b.Units[0].a.Add();
b.Units[0].a.Units[0].SomeField += 100;
bool res= b.Units[0].a.Units[0].Rename("1");
res = b.Units[0].a.Units[0].Rename("1");
Console.ReadKey();
}
這種結構可以用來創建「非均質樹」。
幫助,我需要幫助,只是沒有人...。 [The Beatles]
我使用CopyPaste創建了B和BUnit。 但是,如何使用「宏定義」或「通用」,繼承或其他優雅風格的東西呢? (C#語言) 我認爲沒有理由來描述我所有不成功的嘗試和子問題。已經有話題太長了。 :)
非常感謝,如果您仍然閱讀並理解我想問的問題。
雖然我試圖理解和測試你的代碼,你能告訴我說:我們能避免與構造函數,你描述的,如果我們將使用無參數construcor但增加功能SetContainer(有些PARAMS),以單位類,並使用它的問題在public void Add(T item){list.Add(item); item.SetContainer(一些參數)}。我們也可以在Add()函數內創建項目並使用此函數而不使用參數? – JustOneQuestion
@JustOneQuestion回答你的第一個問題:這個問題還是一樣。你想在基類「UnitBase」中擁有所有常見的功能。這個類並不知道是什麼類型可能從中獲得的,所以'Container'永遠是類型'的IContainer'這是不變的。 –
InBetween
@JustOneQuestion編輯廣泛的基於你的第二個問題,回答'的IContainer'刪除了通用的類型,因爲它沒有在您的特定場景下'T'只能是'UnitBase'做多。另外請注意'Add'現在返回添加的元素,以便您可以獲取對新創建項目的引用。此外,如果'AUnit','BUnit'等具有無參數構造函數以便能夠在'Add'內部創建一個構造函數,則該解決方案可以工作。 –
InBetween