C# 什么';通过指定精确的类引用对象和System.object之间的区别是什么?

C# 什么';通过指定精确的类引用对象和System.object之间的区别是什么?,c#,types,reference,covariance,C#,Types,Reference,Covariance,如果我们有一个类,比如说MyClass,当实例化该类的对象时,这两个类之间的区别是什么: Object obj=new MyClass(); MyClass obj2=new MyClass(); 我知道在.NET中,所有类都派生自System.Object,因此在本例中,obj和obj2变量只包含对对象的引用 但是,有什么区别吗? 如果是,当使用这两种实例化对象的方法时,它是什么?假设您的类有一个名为Name的属性,如果您使用它 Object obj = new MyClass(); 并尝

如果我们有一个类,比如说
MyClass
,当实例化该类的对象时,这两个类之间的区别是什么:

Object obj=new MyClass();
MyClass obj2=new MyClass();
我知道在.NET中,所有类都派生自
System.Object
,因此在本例中,obj和obj2变量只包含对对象的引用

但是,有什么区别吗?


如果是,当使用这两种实例化对象的方法时,它是什么?

假设您的类有一个名为
Name
的属性,如果您使用它

Object obj = new MyClass();
并尝试使用:

obj.Name = "George";
这将是一个编译器错误,因为对象类没有
Name
属性。不过,这也可以:

MyClass obj2 = new MyClass();
obj2.Name = "George";
因为
obj2
是一个
MyClass
。简而言之,为了访问变量的类成员(属性、方法、变量),该变量必须是具有这些成员的类型,或者需要转换为必要的类:

((MyClass)obj).Name = "George";

但是,不断地强制转换变量以获取其成员是不好的,因为它需要额外的CPU周期,并可能导致InvalidCastException。

假设您的类有一个名为
Name
的属性,如果您使用该属性

Object obj = new MyClass();
public class MYclass
    {
        public int Id { get; set; }
    }


class Program
{
    static void Main(string[] args)
    {
        Object obj = new MYclass();
        MYclass mc = new MYclass();

        Console.WriteLine(obj.GetType());
        MYclass mc2 = obj as MYclass;
        Console.WriteLine(mc2.Id);
        Console.WriteLine(mc.Id);

        Console.ReadLine();
    }
}
并尝试使用:

obj.Name = "George";
这将是一个编译器错误,因为对象类没有
Name
属性。不过,这也可以:

MyClass obj2 = new MyClass();
obj2.Name = "George";
因为
obj2
是一个
MyClass
。简而言之,为了访问变量的类成员(属性、方法、变量),该变量必须是具有这些成员的类型,或者需要转换为必要的类:

((MyClass)obj).Name = "George";
但是,不断地强制转换变量以获取其成员是不好的,因为它需要额外的CPU周期,并可能导致InvalidCastException

public class MYclass
    {
        public int Id { get; set; }
    }


class Program
{
    static void Main(string[] args)
    {
        Object obj = new MYclass();
        MYclass mc = new MYclass();

        Console.WriteLine(obj.GetType());
        MYclass mc2 = obj as MYclass;
        Console.WriteLine(mc2.Id);
        Console.WriteLine(mc.Id);

        Console.ReadLine();
    }
}
在上面的代码段中,输出将是

ConsoleApplication1.MYclass
0
0
这告诉您在运行时obj的类型是Myclass。但是,在编译时,它仍然是一个对象,您需要显式强制转换来访问obj中Myclass的属性

在上面的代码段中,输出将是

ConsoleApplication1.MYclass
0
0

这告诉您在运行时obj的类型是Myclass。但是,在编译时它仍然是一个对象,您需要显式强制转换来访问obj中Myclass的属性。

假设
Myclass
直接从
Object
继承,编写
Object obj=new Myclass()
会创建一个
Myclass
对象,但对它的引用类型为
Object
。因此,它不知道类
MyClass
中存在任何公开可用的方法、属性或状态变量,因此如果您尝试调用:

obj.MyClassMethod()


呼叫将失败。除非使用某种形式的强制转换,
obj
唯一可用的方法将是
对象
类公开的方法。

假设
MyClass
直接从
对象继承,编写
对象obj=new MyClass()
创建一个
MyClass
对象,但对它的引用类型为
object
。因此,它不知道类
MyClass
中存在任何公开可用的方法、属性或状态变量,因此如果您尝试调用:

obj.MyClassMethod()


呼叫将失败。除非使用某种形式的强制转换,
obj
唯一可用的方法将是
对象
类公开的方法。

好吧,这一点很简单,当然可以将类实例化为对象,但为什么呢?如果您想使用它的任何内容,您必须将它转换为您的类

使用
DateTime

object obj = new DateTime();
int test = ((DateTime)obj).Second;   // Have to cast here, as object does not contain Second

DateTime obj2 = new DateTime();
int test2 = obj2.Second; // It is a DateTime so all good

var obj3 = new DateTime(); // Type is infered by right hand side assignment
int test3 = obj3.Second; // It is a DateTime so all good

所以,除非类中没有任何东西可以创建为对象,但是为什么要使用类而只使用对象呢。

这是一个很简单的问题,当然可以将类实例化为对象,但是为什么呢?如果您想使用它的任何内容,您必须将它转换为您的类

使用
DateTime

object obj = new DateTime();
int test = ((DateTime)obj).Second;   // Have to cast here, as object does not contain Second

DateTime obj2 = new DateTime();
int test2 = obj2.Second; // It is a DateTime so all good

var obj3 = new DateTime(); // Type is infered by right hand side assignment
int test3 = obj3.Second; // It is a DateTime so all good

所以,除非类中没有任何东西可以创建为对象,否则为什么要使用类而只使用对象呢。

首先:术语。您仅以一种方式实例化MyClass的实例:通过调用其构造函数。您所做的是以两种方式引用实例。这是因为多态性,即类实例可由其实现的任何类型引用的属性。在您编写实例时,引用实例的不同方式之间没有很大区别,但是当您希望使用某些基类型执行某些操作时,可能会有区别。CLR执行从子类型(MyClass)及其基类型(Object)的自动转换。

第一:术语。您仅以一种方式实例化MyClass的实例:通过调用其构造函数。您所做的是以两种方式引用实例。这是因为多态性,即类实例可由其实现的任何类型引用的属性。在您编写实例时,引用实例的不同方式之间没有很大区别,但是当您希望使用某些基类型执行某些操作时,可能会有区别。CLR执行从子类型(MyClass)及其基类型(Object)的自动转换。

尝试在
obj
变量上调用MyClass的方法,您将很快看到差异。这意味着变量的静态类型(在编译时)是
Object
而不是
MyClass
,动态类型(在运行时)是
MyClass
,因此您只能调用
对象上声明的方法(除非您强制转换)。尝试在
obj
变量上调用MyClass的方法,您将很快看到差异。这意味着变量的静态类型(在编译时)是
对象
,而不是
MyClass
,还有dyna