从相应的层次结构中创建ClassObject

时间:2013-10-30 07:15:23

标签: c# .net hierarchy

我有两个类树,它们具有相同的结构。我想从类型创建一个新的类对象,并从另一个结构的相应类创建属性。

这是我的控制结构类:

public class ControlBase
{
    public ControlBase(string name);
    string name;
}
public class ControlA : ControlBase
{
    public ControlA(string name, int val) : base(name);
    int val;
}
public class ControlB : ControlBase
{
    public ControlB(string name, double val) : base(name);
    double val;
}

xml dataitem classes:

public class XMLBase
{
    string name;
}
public class XMLA : XMLBase
{
     int val;
}
public class XMLB : XMLBase
{
     double val;
}

我有一个来自xml结构的对象列表,我的问题是: 如何从控件结构中创建等效的对象列表。

我知道我可以做这样的事情,但我认为这不是一个干净的解决方案。

foreach (XMLBase xmlItem in xmlList)
{
    if(xmlItem is XMLA)
    {
         XMLA toAdd = (XMLA)xmlItem;
         controlList.Add(new ControlA(toAdd.name, toAdd.val));
    }
    if(xmlItem is XMLB)
    ...
}
编辑:我忘了一些限制

  1. 我不应该触摸XML对象,因为它们是生成代码
  2. 我可以有多个价值成员

3 个答案:

答案 0 :(得分:1)

也许你正在寻找一个带有泛型的解决方案(只是一个快速的样本,代码没有编译,只是为了这个想法):

public void <T,T2,T3> MYGenericFunction(IEnumerable<T> xmlList)
    where T: XMLBase<T3>
          T2: new, ControlBase<T3>
{
    foreach (T xmlItem in xmlList)
    {
        T2 item = new T2();
        item.Name = toAdd.name;
        item.Val = toAdd.val;
        controlList.Add(T2);
    }
}

public class<T> ControlBase
{
    public ControlBase();
    public string Name;
    public T Val;
}


public class<T> XMLBase
{
    public string name;
    public T val;
}

答案 1 :(得分:1)

试试这种方式。您将保持层次结构与客户端的连接,并控制在他们知道如何操作的位置复制对象。

public abstract class ControlBase
{
    protected ControlBase() { }      

    public ControlBase(string name)
    {
        this.name = name;
    }

    public abstract string DisplayMe();        

    protected string name;
}


public class ControlA : ControlBase
{
    public ControlA() { }

    public ControlA(string name, int val) : base(name) { this.val = val; }

    int val;

    public override string DisplayMe()
    {
        return val.ToString();
    }
}

public class ControlB : ControlBase
{
    public ControlB(string name, double val) : base(name) { this.val = val; }

    double val;

    public override string DisplayMe()
    {
        return val.ToString();
    } 
}



public abstract class XMLBase
{
    public string Name {get; set;}

    public abstract ControlBase ToControl();

}

public class XMLA : XMLBase
{
    public override ControlBase ToControl()
    {
        return new ControlA(Name, Val);
    }

    public int Val {get; set;}
}

public class XMLB : XMLBase
{       
    public override ControlBase ToControl()
    {
        return new ControlB(Name, Val);
    }

    public double Val {get; set;}
}


public class Client
{
    public static void Run()
    {
        IList<XMLBase> xmlList = new List<XMLBase>();

        xmlList.Add(new XMLA() { Name = "minion1", Val = 1 });
        xmlList.Add(new XMLB() { Name = "minion2", Val = 1.232323 });

        IList<ControlBase> controls = new List<ControlBase>();
        foreach (var xmlItem in xmlList)
        {
            var ctrl = xmlItem.ToControl();
            controls.Add(ctrl);
        }


        foreach (ControlBase ctrlBase in controls)
        {
            Console.Out.WriteLine(ctrlBase.DisplayMe());
        }
    }
}

答案 2 :(得分:0)

如果您可以修改XML类,那么为什么不添加虚拟方法:

public virtal ControlBase ToControl();

然后让每个XML类实现它:

public class XMLBase
{
    string name;

    public virtual ControlBase ToControl()
    {
       return new ControlBase(name);
    }
}
public class XMLA : XMLBase
{
    int val;

    public override ControlBase ToControl()
    {
       return new ControlA(name, val);
    }
}
public class XMLB : XMLBase
{
    double val;

    public override ControlBase ToControl()
    {
       return new ControlB(name, val);
    }
}

现在你的循环看起来像这样:

foreach (XMLBase xmlItem in xmlList)
{
  var control = xmlItem.ToControl();
  controlList.Add(control);
}

这样做的好处是它可以将创建放在知道如何创建它的东西旁边的Control

如果你能够使XMLBase抽象,那么这会更好,因为它也可以让你ToControl抽象。这样派生类将被强制实现它,而不是必须记住覆盖它。