0

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

这是我的控制结构类:

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 数据项类:

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. 我可以有多个值成员
4

3 回答 3

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;
}
于 2014-02-06T08:56:25.000 回答
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());
        }
    }
}
于 2014-02-06T11:00:00.507 回答
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抽象。这样派生类将被迫实现它,而不必记住重写它。

于 2014-02-06T11:12:50.233 回答