从创建基类的子类的克隆副本 [英] Creating a cloned copy of subclass from baseclass

查看:119
本文介绍了从创建基类的子类的克隆副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这种情况:

public class Base
{
    public int i;
}

public class Sub : Base
{
    public void foo() { /* do stuff */}
}

然后我想,因为基地的一个实例获得子的克隆实例(其中i = 17在这种情况下),这样我可以在子类中调用

And then I want to, given an instance of Base get an cloned instance of Sub (with i=17 in this case) so that I can call foo in the subclass.

Base b = new Base { i=17 };
Sub s = CloneAndUpcast(b);
s.foo();



不过,我怎么可以创建 CloneAndUpcast

我在想,是应该可以 - 成员和属性使用反射递归克隆所有基地。但相当一些工作。

I am thinking that is should be possible to recursively clone all of Base-members and properties using reflection. But quite some work.

任何人提供更好,更整洁的想法?

Anyone with better, neater ideas?

PS。在这里,我想用这个场景是一组以树状结构简单类(无循环图或类似的在这里),所有的类都是简单值的持有者。该计划是有实际包含一些业务逻辑的价值,持有人不应该知道的一个愚蠢的层保存所有值,然后一组相似的类(子类)。一般不好的做法是。我认为它的工作原理在这种情况下。

PS. The scenario where I am thinking about using this is a set of "simple" classes in a tree-like structure (no cyclic graphs or similar here) and all the classes are simple value holders. The plan is to have a stupid layer holding all values and then an similar set of classes (the subclasses) that actually contains some business-logic the value-holders shouldn't be aware of. Generally bad practice yes. I think it works in this case.

推荐答案

下面是一个办法(出许多可能性),你可以不喜欢你'再询问。我不知道这是很漂亮,可种丑陋的调试,但我认为它的工作原理:

Here's one way (out of many possibilities) that you could do something like you're asking. I'm not sure this is very pretty and can be kind of ugly to debug, but I think it works:

class BaseClass
{
    public int i { get; set; }

    public BaseClass Clone(BaseClass b)
    {
        BaseClass clone = new BaseClass();
        clone.i = b.i;
        return clone;
    }

}

class SubClass : BaseClass
{
    public int j { get; set; }

    public void foo() { Console.WriteLine("in SubClass with value of i = {0}", i.ToString()); }
}

class Program
{
    static void Main(string[] args)
    {
        BaseClass b1 = new BaseClass() { i = 17 };
        BaseClass b2 = new BaseClass() { i = 35 };

        SubClass sub1 = CloneAndUpcast<SubClass>(b1);
        SubClass sub2 = CloneAndUpcast<SubClass>(b2);

        sub1.foo();
        sub2.foo();
    }

    static T CloneAndUpcast<T>(BaseClass b) where T : BaseClass, new()
    {
        T clone = new T();

        var members = b.GetType().GetMembers(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
        for (int i = 0; i < members.Length; i++)
        {
            if (members[i].MemberType== MemberTypes.Property)
            {
                clone
                    .GetType()
                    .GetProperty(members[i].Name)
                    .SetValue(clone, b.GetType().GetProperty(members[i].Name).GetValue(b, null), null);
            }

        }
        return clone;
    }
}



基本上,如你所说,你可以使用反射来遍历通过对象的属性(我设置 I Ĵ公共属性),并在克隆的对象设置相应的值。关键是使用泛型告诉你处理什么类型与CloneAndUpcast。一旦你这样做,这是非常简单的。

Basically, as you suggested, you use reflection to iterate through the object's properties (I set i and j as public properties) and set the values accordingly in the cloned object. The key is using generics to tell CloneAndUpcast what type you're dealing with. Once you do that, it's pretty straightforward.

希望这有助于。祝你好运!

Hope this helps. Good luck!

这篇关于从创建基类的子类的克隆副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆