C# - 继承方法传递自身对象

3
真正的问题出现在反射和程序集补丁/钩子上。我将举一个简单的例子,以便不太难以理解主要问题。
那么,让我们想象一下我有这些基本类:
public class Vehicle
{
    public string Name;
    public string Price;

    public void DoSomething()
    {
        Main.Test(this);
    }
}

public class Car : Vehicle
{
    public int Wheels;
    public int Doors;
}

在主代码上,我运行了以下命令:

public class Main
{
    public void Start()
    {
        Car testCar = new Car()
        {
            Name = "Test Car",
            Price = "4000",
            Wheels = 4,
            Doors = 4
        };

        testCar.DoSomething();
    }

    public static void Test(Vehicle test)
    {
        // Is this allowed ?
        Car helloWorld = (Car) test;
    }   
}

好的,问题是:

这种类型转换(在静态方法Test中)被允许吗?我会失去Car属性但保留Vehicle属性吗?

如果不正确,是否有其他方法可以实现?

谢谢。


如果这有错,还有其他的解决方案吗?做什么事情? - Ivan Stoev
请参考下面的内容了解向下转型:https://dev59.com/QHI_5IYBdhLWcg3wF_J3 - flo scheiwiller
2
欢迎来到 Stack Overflow。这应该是相对容易测试的东西。那么你试过了吗?如果没有,那就是提问的前提条件。如果你已经尝试过了,那么你遇到了具体的问题吗? - ardila
@IvanStoev 要获取对象作为Car而不是Vehicle。 - Snak
如果是“卡车”呢?我的意思是,想象一下你有另一个类“卡车:车辆”,你如何知道“车辆测试”是“汽车”而不是“卡车”或任何其他派生自“车辆”的类。 - Ivan Stoev
我理解这一点,但我面临的真正问题是:我有一个LightAttachment组件,它具有引用BaseWeapon的属性,但只有RangedWeapons(从BaseWeapon派生)具有Light组件,因此我知道它必须是RangedWeapon。因此,我将BaseWeapon强制转换为RangedWeapon。该代码来自Unity制作的游戏(不是我制作的),我只是通过修补IL代码来修改其中的某些部分。 - Snak
3个回答

5

只有当传入的对象为Car时,才允许将Vehicle转换为Car, 否则会抛出异常。

有一种类型转换不会在类型错误时引发异常:

Car car = test as Car;

这段代码不会抛出异常,但是当Vehicle不是一个Car时,变量car将会变成 null。你可以添加一个if条件来测试转换是否成功:

Car car = test as Car;
if (car != null) {
    ...
}
Bus bus = test as Bus;
if (bus != null) {
    ...
}
Rv rv = test as Rv;
if (rv != null) {
    ...
}

然而,C# 提供了一种更好的解决方案:方法重载可以避免完全转换。
public class Main {
    public static void Test(Car test) {
        ... // This method will be called by Main.Test(this) of a Car
    }
    public static void Test(Bus test) {
        ... // This method will be called by Main.Test(this) of a Bus
    }
    public static void Test(Rv test) {
        ... // This method will be called by Main.Test(this) of an Rv
    }
}

这个代码能够运行,是因为当你进行Main.Test(this)调用时,编译器知道了this变量的确切类型。


这正是我在寻找的,谢谢你的答案! - Snak

2

是的,允许进行类型转换,并且您不会“失去”任何属性。但是,如果Vehicle test实际上不是Car的一个实例,那么您的类型转换将抛出InvalidCastException异常。


感谢您的回答! - Snak

0

是的,允许这样做。它被称为向下转型

请记住,可以通过类型内省来检查引用对象的类型是否确实是正在进行转换的类型或其派生类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接