我想问一个关于C#的问题,让我举个例子。 这是一个简单的示例,我有一个IVehicle接口,它具有Name属性。然后,有一个Car类和一个MotorBicycle类,它们也都实现了IVehicle。 一天,有一家名为“ RedFlag”的汽车工厂,所有产品上都贴有国旗。所以有一个IFlagVehicle接口,它具有FlagColor属性。如果他们的产品是汽车和摩托车,那么我们需要另外两个类别:FlagCar和FlagMotorBicycle。 C#中的演示代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp9
{
#region Example
public interface IVehicle
{
string Name { get; }
}
#region Can't Changed This Region
public class Car : IVehicle
{
public string Name => "Car";
}
public class MotorBicycle : IVehicle
{
public string Name => "MotorBicycle";
}
#endregion
#region User Code
public interface IFlagVehicle : IVehicle
{
string FlagColor { get; }
}
public class FlagCar :
Car,
IFlagVehicle
{
public string FlagColor => "Red";
}
public class FlagMotorBicycle :
MotorBicycle,
IFlagVehicle
{
public string FlagColor => "Red";
}
#endregion
#endregion
class Program
{
static void Main(string[] args)
{
}
}
}
在此代码中,我们可以看到,我们必须在两个类中实现FlagColor属性,并且它们在很多时间都是相同的。 但是在C ++中,我们可以使用speicial模板类,它使用模板参数作为其BaseType,如下所示:
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class IVehicle
{
public:
virtual string GetName() = 0;
};
class Car : public IVehicle
{
public:
virtual string GetName() override
{
return "Car";
}
};
class MotorBicycle : public IVehicle
{
public:
virtual string GetName() override
{
return "MotorBicycle";
}
};
class IFlagVechile
{
public:
virtual string GetFlagColor() = 0;
};
template < typename TBaseType >
class TFlagVechicle :
public TBaseType,
public IFlagVechile
{
public:
virtual string GetFlagColor() override
{
return "Red";
}
};
class FlagCar : public TFlagVechicle<Car>
{
};
class FlagMotorBicycle : public TFlagVechicle<MotorBicycle>
{
};
int main()
{
FlagMotorBicycle fmb;
cout << fmb.GetFlagColor() << " " << fmb.GetName() << endl;
return 0;
}
在这种情况下,我们可以在同一位置实现GetFlagColor函数,以实现这些类的通用实现。 所以,我想知道,C#中有类似的方法吗?否则我必须更改此设计。是否必须更改此层次结构,这是C#中满足此要求的最佳选择? 谢谢!
答案 0 :(得分:0)
这里的挑战之一是C ++模板从两个类继承,这在C#中是不可能的(您只能实现多个接口,而不能继承多个类)。
但是请注意,在面向对象的语言中,应该优先考虑委托而不是继承。实际上,在对象之间委派成员可以提供更大的灵活性,例如一些成员可以省略,一些成员可以有条件地实现,等等。
在这里为您提供的一个选项是委派,从模板到为自己的需要创建的私有成员。相对于可以用作模板参数的类型,它带有附加约束的价格-模板必须创建一个实例,并且可以受new
约束约束。
请注意,该模板将IVehicle
接口委托给该参数,但它自己提供了IFlagVehicle
的实现。
class Program
{
static void Main(string[] args)
{
FlagMotorBicycle fmb = new FlagMotorBicycle();
Console.WriteLine("{0} {1}", fmb.FlagColor, fmb.Name);
Console.ReadLine();
}
}
public interface IVehicle
{
string Name { get; }
};
public class Car : IVehicle
{
public string Name { get; private set; }
public Car()
{
this.Name = "Car";
}
};
public class MotorBicycle : IVehicle
{
public string Name { get; private set; }
public MotorBicycle()
{
this.Name = "Bicycle";
}
};
public interface IFlagVechile
{
string FlagColor { get; }
};
public class TFlagVechicle<T> :
IVehicle, IFlagVechile
where T : class, IVehicle, new()
{
private T t;
public TFlagVechicle()
{
this.t = new T();
this.FlagColor = "Red";
}
public string FlagColor { get; private set; }
public string Name
{
get
{
return t.Name;
}
}
};
public class FlagCar : TFlagVechicle<Car>
{
};
public class FlagMotorBicycle : TFlagVechicle<MotorBicycle>
{
};