C# 将各种 class 对象动态传递给单个方法
C# Pass various class objects to a single method dynamically
假设我有两个 classes 并且我想创建一个方法来处理来自两个 classes 的数据,我如何设置一个可以接受两者的方法将它们创建为它们类型的对象?
Public classs Car:Wheel
{
public Color color {get; set;}
}
Public class Bike:Wheel
{
public bool hasRadio {get ; set;}
public Color color {get; set;}
}
Public class Wheel
{
public WheelRimType {get; set;}
public int WheelSize {get; set;}
}
我想将汽车或自行车的 class 动态传递给一个方法。在那个方法中,如何将它转换为正确的对象,这样我就不必为每个对象编写两次相同的方法?
Car c = new Car();
Bike b = new Bike();
ValidateVehichle(c);
private void ValidateVehicle(Type T??)
{
//convert to either car or bike here
}
使用泛型:
ValidateVehichle<Car>(car);
private void ValidateVehicle<T>(T vehicle)
{
// no convertion needed. use T as the type of the object
T vehicle2 = vehicle;
.....
}
关于泛型的更多信息:https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics
您可以使用泛型并执行如下操作:
void Main()
{
Car car = new Car();
car.color = Color.Black;
car.WheelSize = 22;
ValidateVehicle<Car>(car)
}
private void ValidateVehicle<T>(T vehicle)
{
// You still need to determine what time this object is
T someVehicle = vehicle;
Console.WriteLine("This is a generic method");
}
您也可以使用重载方法。您可以像这样拥有一个具有无限重载的方法名称:
void Main()
{
Car car = new Car();
car.color = Color.Black;
car.WheelSize = 22;
Bike bike = new Bike();
bike.color = Color.Red;
bike.hasRadio = false;
bike.WheelSize = 12;
ValidateVehicle(car);
ValidateVehicle(bike);
}
// You can define other methods, fields, classes and namespaces here
public class Car: Wheel
{
public Color color { get; set; }
}
public class Bike : Wheel
{
public bool hasRadio { get; set; }
public Color color { get; set; }
}
public class Wheel
{
public int WheelSize { get; set; }
}
private void ValidateVehicle(Car car)
{
Console.WriteLine("This is your car method");
}
private void ValidateVehicle(Bike bike)
{
Console.WriteLine("This is your bike method");
}
输出为:
This is your car method
This is your bike method
你的汽车和自行车“有”轮子,但不是“轮子”,所以在考虑继承时你可能想阅读更多关于 has-a-is-a 术语的信息:has-a-is-a-terminology-in-object-oriented-language
我相信你最好为 Car 和 Bike 创建一个基础 class 并在这个基础中放置一个验证方法 class 然后可以在 Car 中实现和自行车。类似于以下内容:
基础 class VehicleBase
将包含公共属性,color
和 Wheels
属性遵循“has-a”逻辑,在示例中,VehicleBase
将包含一个 IEnumerable<T>
,其中 T
是 Wheel
,其中车辆可以有零个或多个车轮。
public abstract class VehicleBase
{
public abstract bool Validate();
public Color color { get; set;}
public IEnumerable<Wheel> Wheels {get; set;}
}
public class Car : VehicleBase
{
public override bool Validate()
{
//do Car validation
}
}
public class Bike : VehicleBase
{
public bool hasRadio {get ; set;}
public override bool Validate()
{
//do Bike validation
}
}
public class Wheel
{
public WheelRimType { get; set;}
public int WheelSize {get; set;}
}
两个经典的可能性
class Vehicle{
}
class Car : Vehicle{
}
class Bike : Vehicle{
}
那你就可以了
private void ValidateVehicle(Vehicle v)
{
//convert to either car or bike here
}
进行验证的惯用方法实际上具有以下内容
abstract class Vehicle{
virtual bool Validate();
}
class Car : Vehicle{
override bool Validate(){
}
}
class Bike : Vehicle{
override bool Validate(){
}
}
你只需要做 vobj.Validate()
其中 vobj 是车辆的实例
也可以使用接口
interface IVehicle{
}
class Car : IVehicle{
}
class Bike : IVehicle{
}
和
private void ValidateVehicle(Vehicle v)
{
//convert to either car or bike here
}
典型的解决方案是引入一个通用接口,以便 ValidateVehicle
可以使用任一类型:
public interface IVehicle{
Color color {get; set;}
}
public class Car:Wheel, IVehicle {
public Color color {get; set;}
}
public class Bike:Wheel, IVehicle
{
public bool hasRadio {get ; set;}
public Color color {get; set;}
}
private void ValidateVehicle(IVehicle vehicle)
{
// Implementation here
}
这显然需要 IVehicle
公开 ValidateVehicle
使用的所有方法和属性。
如果汽车和自行车的验证逻辑不同,您应该将验证方法放在您的车辆类型上。这样每辆车都可以以自己的方式进行验证。
public interface IVehicle{
Color color {get; set;}
bool ValidateVehicle();
}
第三种方法是使用类型检查:
private void ValidateVehicle(object vehicle)
{
if(vehicle is Car car){
...
}
if(vehicle is Bike bike){
...
}
}
但这并不容易维护。假设你介绍了一辆摩托车,如果你使用一个接口,你只需要让你的新车继承那个接口,如果你犯了任何错误,编译器就会抱怨。如果你使用 type-checks,你需要记住你检查类型的所有不同地方,并为你的摩托车添加另一个检查,这很快就会成为维护的噩梦。由于这种类型检查通常不受欢迎。
我猜这是为了作业,但我不喜欢这样的面向对象示例。值得注意的是,汽车 不是 轮子,它 有 轮子,即轮子应该是 属性 而不是 继承.
在演示面向对象时,我通常更喜欢几何,它有很多组合和继承的例子,在实际程序中确实很有用。相比之下,我很难想象车辆继承层次结构实际上在哪里有用。
假设我有两个 classes 并且我想创建一个方法来处理来自两个 classes 的数据,我如何设置一个可以接受两者的方法将它们创建为它们类型的对象?
Public classs Car:Wheel
{
public Color color {get; set;}
}
Public class Bike:Wheel
{
public bool hasRadio {get ; set;}
public Color color {get; set;}
}
Public class Wheel
{
public WheelRimType {get; set;}
public int WheelSize {get; set;}
}
我想将汽车或自行车的 class 动态传递给一个方法。在那个方法中,如何将它转换为正确的对象,这样我就不必为每个对象编写两次相同的方法?
Car c = new Car();
Bike b = new Bike();
ValidateVehichle(c);
private void ValidateVehicle(Type T??)
{
//convert to either car or bike here
}
使用泛型:
ValidateVehichle<Car>(car);
private void ValidateVehicle<T>(T vehicle)
{
// no convertion needed. use T as the type of the object
T vehicle2 = vehicle;
.....
}
关于泛型的更多信息:https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics
您可以使用泛型并执行如下操作:
void Main()
{
Car car = new Car();
car.color = Color.Black;
car.WheelSize = 22;
ValidateVehicle<Car>(car)
}
private void ValidateVehicle<T>(T vehicle)
{
// You still need to determine what time this object is
T someVehicle = vehicle;
Console.WriteLine("This is a generic method");
}
您也可以使用重载方法。您可以像这样拥有一个具有无限重载的方法名称:
void Main()
{
Car car = new Car();
car.color = Color.Black;
car.WheelSize = 22;
Bike bike = new Bike();
bike.color = Color.Red;
bike.hasRadio = false;
bike.WheelSize = 12;
ValidateVehicle(car);
ValidateVehicle(bike);
}
// You can define other methods, fields, classes and namespaces here
public class Car: Wheel
{
public Color color { get; set; }
}
public class Bike : Wheel
{
public bool hasRadio { get; set; }
public Color color { get; set; }
}
public class Wheel
{
public int WheelSize { get; set; }
}
private void ValidateVehicle(Car car)
{
Console.WriteLine("This is your car method");
}
private void ValidateVehicle(Bike bike)
{
Console.WriteLine("This is your bike method");
}
输出为:
This is your car method
This is your bike method
你的汽车和自行车“有”轮子,但不是“轮子”,所以在考虑继承时你可能想阅读更多关于 has-a-is-a 术语的信息:has-a-is-a-terminology-in-object-oriented-language
我相信你最好为 Car 和 Bike 创建一个基础 class 并在这个基础中放置一个验证方法 class 然后可以在 Car 中实现和自行车。类似于以下内容:
基础 class
VehicleBase
将包含公共属性,color
和Wheels
属性遵循“has-a”逻辑,在示例中,VehicleBase
将包含一个IEnumerable<T>
,其中T
是Wheel
,其中车辆可以有零个或多个车轮。
public abstract class VehicleBase
{
public abstract bool Validate();
public Color color { get; set;}
public IEnumerable<Wheel> Wheels {get; set;}
}
public class Car : VehicleBase
{
public override bool Validate()
{
//do Car validation
}
}
public class Bike : VehicleBase
{
public bool hasRadio {get ; set;}
public override bool Validate()
{
//do Bike validation
}
}
public class Wheel
{
public WheelRimType { get; set;}
public int WheelSize {get; set;}
}
两个经典的可能性
class Vehicle{
}
class Car : Vehicle{
}
class Bike : Vehicle{
}
那你就可以了
private void ValidateVehicle(Vehicle v)
{
//convert to either car or bike here
}
进行验证的惯用方法实际上具有以下内容
abstract class Vehicle{
virtual bool Validate();
}
class Car : Vehicle{
override bool Validate(){
}
}
class Bike : Vehicle{
override bool Validate(){
}
}
你只需要做 vobj.Validate()
其中 vobj 是车辆的实例
也可以使用接口
interface IVehicle{
}
class Car : IVehicle{
}
class Bike : IVehicle{
}
和
private void ValidateVehicle(Vehicle v)
{
//convert to either car or bike here
}
典型的解决方案是引入一个通用接口,以便 ValidateVehicle
可以使用任一类型:
public interface IVehicle{
Color color {get; set;}
}
public class Car:Wheel, IVehicle {
public Color color {get; set;}
}
public class Bike:Wheel, IVehicle
{
public bool hasRadio {get ; set;}
public Color color {get; set;}
}
private void ValidateVehicle(IVehicle vehicle)
{
// Implementation here
}
这显然需要 IVehicle
公开 ValidateVehicle
使用的所有方法和属性。
如果汽车和自行车的验证逻辑不同,您应该将验证方法放在您的车辆类型上。这样每辆车都可以以自己的方式进行验证。
public interface IVehicle{
Color color {get; set;}
bool ValidateVehicle();
}
第三种方法是使用类型检查:
private void ValidateVehicle(object vehicle)
{
if(vehicle is Car car){
...
}
if(vehicle is Bike bike){
...
}
}
但这并不容易维护。假设你介绍了一辆摩托车,如果你使用一个接口,你只需要让你的新车继承那个接口,如果你犯了任何错误,编译器就会抱怨。如果你使用 type-checks,你需要记住你检查类型的所有不同地方,并为你的摩托车添加另一个检查,这很快就会成为维护的噩梦。由于这种类型检查通常不受欢迎。
我猜这是为了作业,但我不喜欢这样的面向对象示例。值得注意的是,汽车 不是 轮子,它 有 轮子,即轮子应该是 属性 而不是 继承.
在演示面向对象时,我通常更喜欢几何,它有很多组合和继承的例子,在实际程序中确实很有用。相比之下,我很难想象车辆继承层次结构实际上在哪里有用。