我的大脑会爆炸。 :)因此,我想从您那里获得帮助。
请考虑我的问题,就像只是程序员难题一样。 (实际上。也许对您来说这是一个非常简单的问题,但对我而言不是。)

需要创建对象数组。例如列表,其中T是类。 (我将在下面描述T类)。此外,还需要创建“容器”,其中将包含此数组以及与此数组一起使用的一些方法。例如Add(),Remove(int IndexToRemove)。
T类必须具有字段“ Container”,这样,数组的每个元素都将能够知道其包含在何处,并可以访问其容器的字段和方法。注意,在这种情况下,Class 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容器字段”?我们创建字段公共字符串Name {get; private set;}(实际上是属性,但没关系)。而且我们还希望能够更改此字段的值,例如方法[Class AUnit] public bool Rename(string newName)();。此方法的主要思想是仅在数组(公共列表单元;)中没有一个元素具有与newName相同的名称的情况下更改Name字段。但是要实现这一点,重命名方法必须有权访问当前使用的所有名称。这就是为什么我们需要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类非常相似。最后,这个难题的主要问题是我们如何做到这一点?当然,我可以复制粘贴并修改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();
}


此构造可用于创建“非均匀树”。

帮忙,我需要别人的帮助,但没有人……。 [披头士]

我使用CopyPaste创建了B和BUnit。
但是,如何使用“宏定义”或“泛型”,继承或其他优雅的样式来完成呢? (C#语言)
我认为没有理由描述我所有的失败尝试和子问题。已经话题太长。 :)

非常感谢您仍然阅读并理解我的要求。

最佳答案

您需要实现一个基本类型,将其称为UnitBase,具有所有常用功能。我将通过以下方式构建代码:


为您的容器创建一个接口,这样您就可以将实现更改为性能更高的解决方案,而无需修改要添加到容器中的元素。

public interface IContainer
{
    Q Add<Q>() where Q : UnitBase, new();
    IEnumerable<UnitBase> Units { get; }
}

按照1中所述的想法,为什么不使搜索逻辑属于容器?这更有意义,因为它主要取决于容器的实现方式:

public interface IContainer
{
    Q Add<Q>() where Q : UnitBase, new();
    IEnumerable<UnitBase> Units { get; }
    bool Contains(string name);
}


IContainer的特定实现可以如下:

public class Container : IContainer
{
    public Container()
    {
        list = new List<UnitBase>();
    }

    private List<UnitBase> list;

    public Q Add<Q>() where Q: UnitBase, new()
    {
        var newItem = Activator.CreateInstance<Q>();
        newItem.SetContainer(this);
        list.Add(newItem);
        return newItem;
    }

    public IEnumerable<UnitBase> Units => list.Select(i => i);
    public bool Contains(string name) =>
        Units.Any(unit => unit.Name == name);
}

为您的AUnitBUnit类型创建基类,以凝聚所有常用功能:

public abstract class UnitBase
{
    protected UnitBase()
    {
    }

    public IContainer Container { get; private set; }
    public int SomeField;
    public string Name { get; private set; }
    public void SetContainer(IContainer container)
    {
        Container = container;
    }

    public bool Rename(String newName)
    {
         if (Container.Contains(newName))
             return false;

        this.Name = newName; //No need to use String.Copy
        return true;
    }
}

实施您的具体类型:

public class BUnit : UnitBase
{
    public int SpecificBProperty { get; private set; }
    public BUnit()
    {
    }
}



这种方法的缺点?好吧,容器必须是<UnitBase>类型,我已经删除了泛型类型,因为在这种特殊情况下它实际上没有做很多事情,因为它在泛型类型中是不变的。

另外,请记住,类型系统中的任何事物都不能避免以下情况:

myContainer.Add<BUnit>();
myContainer.Add<AUnit>();


如果在同一个容器中没有两种不同的类型,那么整个设置过程就会崩溃。以前的解决方案中也存在此问题,因此它不是新问题,我只是忘记指出了。

07-24 19:58