这可能是重复的,但我找不到类似的问题。我不明白如何在没有数据丢失的情况下对基类型进行隐式转换。例如,我创建了类Person
:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
现在,当我这样做时:
object personAsObject = new Person { Name = "Foo", Age = 1 };
var person = (Person) personAsObject;
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
object
如何保留属性Name
和Age
的值,因为它只包含4种方法Equals
,GetHashCode
,{ {1}}和GetType
?为什么对子类的强制转换抛出ToString
?我希望这是可能的,因为如果成员不是私人的话,他们就会被继承。
答案 0 :(得分:9)
所有关于参考文献。
personAsObject
不是对象的实例。
当您调用new Person
时,您在托管内存中创建了Person
的实例。
变量personAsObject
是一个引用:指向Person
对象所在的托管内存位置的指针。
同样适用于person
:它不是Person
的实例,它是对Person
的引用(恰好是personAsObject
是内存中VARIABLES MANAGED MEMORY
========= ==============
personAsObject----| +-----------------+
|---->| Person Instance |
person------------| +-----------------+
引用的同一个对象。
echo
答案 1 :(得分:1)
用一个过度使用的例子来解释 - 这不一定是良好类设计的一个例子:
public class Employee
{
public string Name { get; set; }
public Guid EmployeeId { get; set; }
}
public class Manager : Employee
{
public IEnumerable<Employee> DirectReports { get; set; }
}
如果您将Manager
转换为Employee
var manager = GetManager(guid employeeId);
var employee = manager as Employee;
或
var employee = (Employee)manager;
您没有将Manager
变成Employee
,因为Manager
已经是Employee
。
实际上,你所说的是你不关心这个对象是什么,而不是Employee
。因为在某些情况下你可能不在乎。假设您要创建一个员工列表 - List<Employee>
- 接近他们的五周年纪念日,以便您可以邀请他们参加聚会。您可以将每种Employee
添加到该列表中,这一点很重要。
这也使多态性成为可能。另一个常见的例子:
public interface IAnimal
{
string MakeSound();
}
public class Cow : IAnimal
{
public string MakeSound()
{
return "Moo";
}
}
public class Giraffe : IAnimal
{
public string MakeSound()
{
return "I don't make any sound. Bad example.";
}
}
现在你可以这样做:
var animals = new List<IAnimal>();
animals.Add(new Cow());
animals.Add(new Giraffe());
foreach(var animal in animals) // or IAnimal in animals
{
Console.WriteLine(animal.MakeSound());
}
将显示
武
我没发出任何声音。不好的例子。
当您浏览List<IAnimal>
中的项目时,您不知道每个项目的实际课程。您所知道的是,每个项目都是IAnimal
并实现MakeSound()
。它不会改变每个的“具体”类型。它只是意味着为了你正在做的事情,你不关心具体的类型。
这使各种各样的事情成为可能。你可以拥有这样的课程
public class Cow : IAnimal, ITastesGood
{
public string MakeSound()
{
return "Croak";
}
}
var cow = new Cow();
var animals = new List<IAnimal>();
var food = new List<ITastesGood>();
animals.Add(cow);
food.Add(cow);
Cow
的同一个实例可以转换为它继承的任何类或它实现的任何接口。