我的大脑会爆炸。 :)所以我想从你那里得到帮助。 请考虑一下我的问题,例如关于程序员谜题。 (其实,也许这对你来说是很容易的问题,但不适合我)。继承泛型类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