考虑C#
中的以下代码class TestClass
{
public int Int { get; set; }
public string Str { get; set; }
}
TestClass t = new TestClass();
object ob = new TestClass();
现在根据我的理解,t和ob变量都包含TestClass对象的引用值。但是为什么t能够访问属性而ob不是?
答案 0 :(得分:3)
编译器根据变量的类型确定变量上可用的哪些方法和字段,而不是变量包含的类型。为了确定变量实际包含的内容,编译器必须做一些在一般情况下被证明是不可判定的(即,不可能的),并且在更具体的情况下至少相当困难。
现在是记住编译时和运行时之间差异的好时机。编译器处理代码并生成程序集时会发生编译时的事情。当程序实际运行时会发生运行时的事情。在编译时,编译器不知道哪些变量包含(您必须运行程序才能实现)。它只能推断变量可能包含的内容,因此它不会让您根据变量可能包含或不包含的内容指定行为。其他语言可以让你通过简单地不检查类型并推迟确定调用哪个函数或字段来访问直到运行时来逃避这一点。 C#不是这样的语言(dynamic
变量除外)。
答案 1 :(得分:0)
由于C#是强类型语言,即使TestClass是一个对象(因为每个类都是一个对象),它都是一个特定的对象。
对象是.net中最基本的引用类型 一个对象只有最常见的属性&每种参考类型应具有的方法 默认情况下,每个引用类型都继承一个对象,甚至是TestClass。想象一下这样的事情:
class TestClass : object
{
public int Int { get; set; }
public string Str { get; set; }
}
顺便说一句,你可以做这些事情(如果你真的坚持的话):
object ob = new TestClass();
string str = (ob as TestClass).Str; // will work with casting.
var ob = new TestClass(); // using a var across types.
string str = ob.Str;
答案 2 :(得分:0)
Object是TestClass的超类,需要先显式转换为TestClass才能访问任何特定于TestClass的成员或方法。
答案 3 :(得分:0)
C#中的所有类都继承自Object类,在您的情况下
object ob = new TestClass();
ob对象被认为是Object类的实例(超类的实例),因此它无法访问类TestClass
(子类)的属性
答案 4 :(得分:0)
为了能够使用属性,您应该将对象强制转换为相关的类:
class TestClass
{
public int Int { get; set; }
public string Str { get; set; }
}
TestClass t = new TestClass();
object ob = new TestClass();
Console.WriteLine(((TestClass)ob).Str );
您可以在此处找到有关类型转换的更多信息:
答案 5 :(得分:0)
我想这是因为编译时和运行时之间的区别。 Object
仅在应用程序的运行时被转换为TestClass
,而在编译时它仍然是对象。这意味着在编译时只有object
属性可用,因为转换为TestClass
实际上还没有发生。
答案 6 :(得分:0)
你有效地在C#,Object中一直追溯到所有的根类。当你向上转换时,你会限制特征,这在协方差和逆变中是可以预期的。
想象
AbstractCar (has turnOn turnOff)
SlowCar (has turnOn turnOff)
FastCar (has turnOn turnOff turboBoost)
如果你有代码
AbstractCar myCar = SomeFunctionThatCreatesACar();
如何在不使用反射的情况下判断返回的汽车是SlowCar还是FastCar?
因此,如果您可以在AbstractCar上使用.turboBoost,那么您有可能在慢速汽车上调用它,而这种情况不会起作用。
您可以安全地使用turnOn和turnOff,因为它们是AbstractCar的一部分。
如果你想要,你可以使用带反射检查的向下投射。
if (myCar is FastCar)
{
((FastCar)myCar).turboBoost();
}
但它并没有真正被认为是良好的做法,因为它打破了#34;告诉,不要问"原理
答案 7 :(得分:0)
简短回答是:ob
属于object类型,虽然它包含对TestClass
对象的引用,但在编译时它无法知道关联的成员。
object
是.Net层次结构中所有类的基类。
支持.NET Framework类层次结构中的所有类 为派生类提供低级服务。这是终极的 .NET Framework中所有类的基类;它是它的根源 类型层次结构。
但请记住Not everything derived from object
由于System.Object
是所有类的基类,因此以下分配有效。
object ob = new TestClass();
由于继承,基类对象可以保存派生类的引用,但它不了解子成员。 ob
的观点仅限于其成员。
您可能会看到Inheritance C#
另一方面,TestClass
是System.Object
(隐式)的子类。它可以访问基类成员,例如GetHashCode
,Equals
,GetType
,ToString
等,