public class Car
{
private string make;
private string model;
public Car(string make, string model)
{
this.make = make;
this.model = model;
}
public virtual void Display()
{
Console.WriteLine("Make: {0}", make);
Console.WriteLine("Model: {0}", model);
}
public string Make
{
get{return make;}
set{make = value;}
}
public string Model
{
get{return model;}
set{model = value;}
}
}
public class SuperCar:Car
{
private Car car;
private int horsePower;
public SuperCar(Car car)
{
this.car = car;
}
public int HorsePower
{
get{return horsePower;}
set{horsepower = value;}
}
public override void Display()
{
base.Display();
Console.WriteLine("I am a super car");
}
当我做
之类的事情时Car myCar = new Car("Porsche", "911");
SuperCar mySupcar = new SuperCar(myCar);
mySupcar.Display();
我只得到“我是超级跑车”,但不是我的基类属性。我应该在SuperCar构造函数中显式分配我的基类的属性吗?事实上,我正在尝试使用Decorator模式,我想要一个类向基类添加行为。
答案 0 :(得分:8)
或者:
public class Car
{
public Car(string make, string model)
{
this.make = make;
this.model = model;
}
public Car (Car car):this(car.Make, Car.Model){}
}
public class SuperCar : Car
{
SuperCar(Car car): base(car){}
}
通过这种方式,您可以从汽车继承任何类,并从提供的对象中填充汽车内容。继承的对象不需要知道要设置什么。它们只是将当前的Car对象传递给基类,它就能完成工作。
答案 1 :(得分:5)
我可能会在这里来晚一点,但是如果有人发现这个有用的话:
您可以使用反射。它需要的代码多于你提出的代码,但我认为它仍然提供了你正在寻找的简洁。
public SuperCar(Car car)
{
var props = typeof(Car).GetProperties().Where(p => !p.GetIndexParameters().Any());
foreach (var prop in props)
{
if (prop.CanWrite)
prop.SetValue(this, prop.GetValue(car));
}
// Set SuperCarcentric properties
// .
// .
// .
}
我从你的例子中明确地写了这个,以清楚地说明这个概念,但我认为这最好是一个通用方法,可以在你的解决方案的所有类似实例中使用。
希望这有帮助。
答案 2 :(得分:1)
查看您的代码我不确定它是如何编译的。你的构造函数是错误的,因为基础构造函数不知道如何运行类型为car的构造函数。看起来您正在尝试实现装饰器模式但尚未正确完成。您应该拥有的ICar
界面实际上是Display()
,SuperCar
car.Display()
你应该调用public interface ICar
{
string Make {get; set;}
string Model {get; set;}
void Display();
}
public class Car :ICar
{
private string make;
private string model;
public Car(string make, string model)
{
this.make = make;
this.model = model;
}
public virtual void Display()
{
Console.WriteLine("Make: {0}", make);
Console.WriteLine("Model: {0}", model);
}
public string Make
{
get{return make;}
set{make = value;}
}
public string Model
{
get{return model;}
set{model = value;}
}
}
public class SuperCar:ICar
{
private ICar car;
private int horsePower;
public SuperCar(ICar car)
{
this.car = car;
}
public string Make
{
get{return car.Make;}
set{car.Make = value;}
}
public string Model
{
get{return car.Model;}
set{car.Model = value;}
}
public int HorsePower
{
get{return horsePower;}
set{horsepower = value;}
}
public override void Display()
{
car.Display();
Console.WriteLine("I am a super car");
}
你还需要在超级跑车上实施制造和模型并让他们返回汽车。制造& car.Model正确实现装饰模式。
{{1}}
答案 3 :(得分:0)
将私有属性更改为受保护的属性,除了创建它们的类之外,任何人都无法访问private,而受保护的变量可以由继承的类访问。
答案 4 :(得分:0)
是的,要让这个工作,你需要设置如下的基本构造函数:
public SuperCar(Car car):base(car.make,car.model)
{
this.car = car;
}
答案 5 :(得分:0)
您还没有完全实现decorator pattern
你需要一个抽象的基类来装饰装饰的汽车
public abstract class CarDecorator
{
protected Car DecoratedCar { get; private set; }
protected CarDecorator(Car decoratedCar)
{
DecoratedCar = decoratedCar;
}
}
public class SuperCar : CarDecorator
{
public SuperCar(Car car)
: base(car)
{
}
public int HorsePower
{
get { return horsePower; }
set { horsepower = value; }
}
public override void Display()
{
DecoratedCar.Display()
Console.WriteLine("Plus I'm a super car.");
}
}
答案 6 :(得分:0)
基于@JoshWheelock回答我写了这个方法,我把它放在我的Xamarin项目的共享文件中
它克隆类,所以你可以用来复制女继承人的基础classe,你可以调整 T param
//...
#if WINDOWS_UWP
using System.Reflection;
#endif
//...
public void CloneIn<T>(T src, T dest)
{
#if WINDOWS_UWP
var props = typeof(T).GetTypeInfo().DeclaredProperties.Where(p => !p.GetIndexParameters().Any());
#else
var props = typeof(T).GetProperties().Where(p => !p.GetIndexParameters().Any());
#endif
foreach (var prop in props)
{
if(prop.SetMethod!=null)
prop.SetValue(dest, prop.GetValue(src));
}
}
尚未在Android和iOS中测试过,关于Android我的模拟器自从一周以后就已经停止正常工作......