【发布时间】:2018-02-15 13:02:47
【问题描述】:
我试图了解一些 C# 转换条件背后的逻辑,这是我的测试代码
文件:example.cs
public class Animal { public string animal_name = "Animal"; }
public class Dog : Animal { public string dog_name = "Dog"; }
public class Class1
{
public void createObjects()
{
var animal1 = new Animal();
printAnimalName(animal1);
}
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name);
}
}
在我的 Main 函数中,我调用 createObjects 函数如下:
static void Main(string[] args)
{
Class1 c1 = new Class1();
c1.createObjects();
Console.ReadLine();
}
运行上面的代码会报错
System.NullReferenceException:'Object reference not set to an instance of an object'
我知道这是应该的方式,由于演员:
var dog1 = my_animal as Dog;
但它背后的逻辑是什么?为什么我们不能通过传递一个 Animal 对象来调用函数 printAnimalName 呢?根据我的理解,这应该是可能的,因为该函数需要一个 Animal 对象。
【问题讨论】:
-
animal1 是 Animal 类型,而不是 Dog 类型。尝试使 Animal 成为一个抽象类,看看会发生什么。你应该像这样使用它: var animal1 = new Dog();
-
as会尝试投射它,如果它不能投射它会返回default。 -
if (my_animal is Dog dog1) Console.WriteLine(dog1.dog_name); else Console.WriteLine("Not a dog!");使用较新的 c# 通过is进行转换是首选。使用as,您需要强制转换&& 测试,使用is,您需要包含测试。 -
如果您只尝试使用已知的
Animal而不是尝试转换为Dog,它将起作用。如果您需要Dog,则方法的参数应采用Dog而不是Animal。 -
你的例子不太好。首先,一条狗将同时拥有
dog_name和animal_name。其次,如果你想在你的方法中处理一个dog实例,你应该传递一个dog实例给它。如果在方法内部只能使用派生类,则没有必要将基类作为参数。
标签: c#