gpt4 book ai didi

c# - 有没有一种方法可以通过类的层次结构来分配属性?

转载 作者:行者123 更新时间:2023-11-30 17:41:05 25 4
gpt4 key购买 nike

请看下面的类层次结构:

Person [age, country, hair color, eyes color..]
Adult [job, car..]
Man [favorite beer..]
Woman [purse..]
Child [school, favorite toy]
Boy
Girl [doll]

每个派生类都有特定的属性:例如,成人可能有工作,但 child 没有。一个女孩可能有一个最喜欢的洋娃娃和一个学校的名字。一个男孩也有学校的名字,但他没有喜欢的娃娃。

我想实现一个克隆 Boy 的方法(返回一个具有完全相同属性的 Boy 对象)。我不想返回 Boy 并手动设置从 ChildPerson 继承的所有属性,而是想避免这种情况。

注意:ChildAdultPerson是抽象类。

注意 2:所有这些人都有我不想复制的复杂引用,在某些情况下我只想复制那些引用的 ID,但这应该手动完成,所以我需要对克隆的对象进行一些控制.

我想到了 Person 中的一个虚方法,它在每个子类中都被重写了,但是由于无法实例化 Person 我不确定如何实现这种行为.

最佳答案

取 3 ...

解决方案一:

我的首选方法是使用 ICopyTo。我认为它比其他任何东西都更可取,因为它强制具有要复制到的正确类型的对象。它还同时进行克隆和复制。更易于维护。

使用界面也有助于做正确的事。不要忘记调用 base.CopyTo ...

此外,我们可以说 CopyTo 是 Fluent interface 的一部分

public interface ICopyTo<T>
{
T CopyTo(T target);
}

public abstract class Person : ICopyTo<Person>, ICloneable
{
public Person CopyTo(Person person)
{
person.Age = Age;
person.Country = Country;
return person;
}

public abstract object Clone();

public int Age { get; set; }
public string Country { get; set; }
}

public abstract class Adult : Person, ICopyTo<Adult>, ICloneable
{
public Adult CopyTo(Adult adult)
{
base.CopyTo(this);
adult.Car = Car;
return adult;
}

public string Car { get; set; }
}

public class Man : Adult, ICopyTo<Man>, ICloneable
{
public Man CopyTo(Man man = null)
{
if (man == null)
{
man = new Man();
}
base.CopyTo(this);
man.Beer = Beer;

return man;
}


public string Beer { get; set; }

public override object Clone()
{
return CopyTo();
}
}

public class Woman : Adult, ICopyTo<Woman>, ICloneable
{
public Woman CopyTo(Woman woman = null)
{
if (woman == null)
{
woman = new Woman();
}
base.CopyTo(this);
woman.Purse = Purse;
return woman;
}

public string Purse { get; set; }

public override object Clone()
{
return CopyTo();
}
}

public class Test
{
public static void Go()
{
Man man1 = new Man() {Age = 10, Beer = "Bud", Country = "Canada"};
Man man2 = new Man();
man1.CopyTo(man2); // Real copy

Woman woman1 = new Woman() {Age = 32, Country = "USA", Purse = "Anything"};
Woman woman2 = woman1.CopyTo(); // Cloning

List<Person> adults = new List<Person>();
adults.Add(man1);
adults.Add(man2);
adults.Add(woman2);

Person person0 = adults[0].Clone() as Person;
Person person1 = adults[1].Clone() as Person;
Person person2 = adults[2].Clone() as Person;
}
}

解决方案 2:(接近解决方案 1,但仅在基类使用 ICloneable)

public interface ICopyTo<T>
{
T CopyTo(T target);
}

public abstract class Person : ICopyTo<Person>, ICloneable
{
public virtual Person CopyTo(Person person)
{
if (person == null)
{
throw new ArgumentNullException("person can't be null");
}

person.Age = Age;
person.Country = Country;
return person;
}

public object Clone()
{
return CopyTo(null);
}

public int Age { get; set; }
public string Country { get; set; }
}

public abstract class Adult : Person, ICopyTo<Adult>, ICloneable
{
public Adult CopyTo(Adult adult)
{
if (adult == null)
{
throw new ArgumentNullException("adult can't be null");
}

base.CopyTo(this);
adult.Car = Car;
return adult;
}

public override Person CopyTo(Person person)
{
return CopyTo(person as Adult);
}

public string Car { get; set; }
}

public class Man : Adult, ICopyTo<Man>
{
public Man CopyTo(Man man = null)
{
if (man == null)
{
man = new Man();
}
base.CopyTo(this);
man.Beer = Beer;

return man;
}

public override Person CopyTo(Person person)
{
return CopyTo(person as Man);
}

public string Beer { get; set; }
}

public class Woman : Adult, ICopyTo<Woman>
{
public Woman CopyTo(Woman woman = null)
{
if (woman == null)
{
woman = new Woman();
}
base.CopyTo(this);
woman.Purse = Purse;
return woman;
}

public override Person CopyTo(Person person)
{
return CopyTo(person as Woman);
}

public string Purse { get; set; }
}

public class Test
{
public static void Go()
{
Man man1 = new Man() {Age = 10, Beer = "Bud", Country = "Canada"};
Man man2 = new Man();
man1.CopyTo(man2); // Real copy

Woman woman1 = new Woman() {Age = 32, Country = "USA", Purse = "Anything"};
Woman woman2 = woman1.CopyTo(); // Cloning

List<Person> adults = new List<Person>();
adults.Add(man1);
adults.Add(man2);
adults.Add(woman2);

Person person0 = adults[0].Clone() as Person;
Person person1 = adults[1].Clone() as Person;
Person person2 = adults[2].Clone() as Person;
}
}

解决方案 3:

public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}

// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}

IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}

关于c# - 有没有一种方法可以通过类的层次结构来分配属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33507761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com