【问题标题】:C# Why can I access a non static class' methods and properties via a property, without creating an instance of that class first?C# 为什么我可以通过属性访问非静态类的方法和属性,而无需先创建该类的实例?
【发布时间】:2020-02-20 12:37:31
【问题描述】:

我对 C# 非常陌生,并且一直在学习 C# 和 .NET Core 的一系列基础培训课程。在这些课程中,我不断地被告知,除非一个类是静态的,否则我必须通过“new”关键字创建一个类的新实例来访问它的属性和方法。但是,在一个培训课程(.NET Core 基础知识)中,有一个示例没有解释,但情况似乎并非如此,我需要帮助来理解原因。

课程有“餐厅”和“DetailModel”两个课程。 Restaurant 类中的所有方法和属性都是公共的,Restaurant 类及其属性和方法不是静态的。在 DetailModel 类(位于单独的类文件中)中,创建了一个名为 Restaurant 的新属性,其类型如下所示:

public Restaurant Restaurant { get; set; }

通过这个属性,我现在可以访问 Restaurant 类的所有方法和属性,而无需创建 Restaurant 类的新实例。我的问题是,当我不断被告知如果不创建该类的新实例就无法访问非静态类的方法和属性时,为什么允许我设置具有该类类型的属性然后访问那个类的方法和属性,不用通过'new关键字创建那个类的新对象?任何帮助将不胜感激。

我使用的 .NET Core 框架的版本是 2.2。

查看以下两个简化类的代码:

public class Restaurant
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Location { get; set; }
        public CusineType Cuisine { get; set; }

    }

 public class DetailModel : PageModel
    {

        public Restaurant Restaurant { get; set; }

        public void OnGet()
        {
            Restaurant.Name = "Test Restaurant";
        }
    }

【问题讨论】:

  • 我看不到你,作为一个人类,但知道你是人类,我可以假设你有手、脚和头。所以对于你指定的类也是如此,变量的类型是有这些属性,如果填充了,那么这些属性存在,如果你在没有填充的时候尝试使用它们,你当然会得到一个 nullexception 错误
  • 在示例中,您访问的不是类的 Name 属性,而是您的属性对象。但是如果你只运行这段代码,它会抛出一个 NullReferenceException,因为它还没有被初始化(在例子中)。也许在类外或类内进行一些初始化。在 Visual Studio 中,您可以右键单击该属性并单击以查找所有参考,这将向您显示使用该特定变量/属性的内容。
  • 我认为如果您不将属性命名为与类型相同的名称,则不会那么混乱。使用public Restaurant MyRest {get;set;},您会看到MyRest.Name 不是 访问该类型的静态属性,而是访问MyRest 实例的实例属性。这个实例目前可能是null 是一个不同的问题。
  • 运行代码,你会看到你得到一个 NullReferenceException,这正是因为没有创建 Restaurant - 该属性尚未设置。
  • 感谢大家的帮助,尤其是@René Vogt,它真的让我明白了发生了什么。

标签: c# oop methods


【解决方案1】:

检查属性定义:

public Restaurant Restaurant { get; set; }

这是 Restaurant 类的实例,也称为 Restaurant。

在这一行

Restaurant.Name = "Test Restaurant";

您访问的不是类的属性,而是实例的属性。如果您想看看我在说什么,请将实例重命名为 RestaurantInstance。

Restaurant 类的实际实例将在 DetailModel 类的实例化时创建。它的默认构造函数会将 Restaurant 创建为 null,而不是 new Restaurant()。

【讨论】:

    【解决方案2】:

    您缺少的是在DetailModel 中有一个Restaurant 类型的属性,也称为Restaurant。线

    Restaurant.Name = "Test Restaurant";
    

    指的是该属性。为清楚起见,您可以想象在Restaurant 前面有一个this,如下所示:

    this.Restaurant.Name = "Test Restaurant";
    

    将属性命名为与它们来自的类相同可能会造成混淆,应尽可能避免(这通常发生在类型为 Color 并且也命名为 Color 的颜色属性中)。

    注意:要使名称设置生效,该属性需要在之前的某个位置进行初始化(即您所期望的 new Restaurant())。

    【讨论】:

      猜你喜欢
      • 2017-09-18
      • 2012-10-30
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多