我一直在用C++编程,但现在正在try 学习C#.我试图在C#中创建多个对象并使用它们的数据.但是,它并没有按照我想要的方式工作.

这是我试过的代码.

class Students
{         
    static void Main(string[] args)
    {
        StudentInfo[] student = new StudentInfo[2];

        student[0] = new StudentInfo(100, 4);
        student[1] = new StudentInfo(101, 3);

        for (int i = 0; i < 2; i++)
        {
            Console.WriteLine(student[i].studentNo);
            Console.WriteLine(student[i].GPA);
        }
    }

    class StudentInfo
    {
        public int studentNo, GPA;
            
        public StudentInfo(int cc, int ct)
        {
            int studentNo = cc;
            int GPA = ct;
        }
    }
}

我本以为会得到

100
4
101
3

但我真正看到的是

0
0
0
0

它给了我一个警告,这样"警告CS0649:字段'学生.学生信息. GPA'从来没有分配给,并将永远有."

如何在对象中正确设置这些值?

推荐答案

通常,在C#中,我们用于类级别变量的命名约定与本地级别变量不同.我建议你这样写:

    class StudentInfo
    {
        private int _studentNo;
        public int StudentNo {get => _studentNo; set => _studentNo = value; }

        public int Gpa { get; set;}
      
            
        public StudentInfo(int cc, int ct)
        {
            _studentNo = cc;
            Gpa = ct;
        }
    }

这里面有一点,让我们再看一遍:

  • 在我的代码中,_studentNo以上是私有fieldStudentNo是公有property.您不应该公开字段;只公开属性,因为您可以更好地控制设置值时外部代码可以做什么.属性可以包含更多的代码,例如范围判断,而如果您公开一个字段public,它可以设置为任何内容.此外,您经常会发现像JSON序列化器和数据绑定自动化这样的东西默认只序列化/绑定属性,因此您可能会绕圈子思考"为什么我的序列化器不输出所有这些明确存在于类中的数据?噢..是的..它们都是田地,不是财产."

  • 私有成员通常为_namedLikeThis个,并且仅在班级内被引用.在这门课上,你可以参考_studentNoStudentNo;两者都可以.在课外,你只能参考StudentNo

  • 将私有成员命名为_likeThis意味着您可以声明本地成员likeThis,并且您可以一目了然地知道您正在查看的变量是在类级别声明的还是在本地级别声明的.C#允许您创建与类级别同名的本地级别变量,如果您不确定需要的是类级别变量,则优先使用本地变量:

    class StudentInfo
    {
        private int studentNo; //class level var
            
        public StudentInfo(int cc, int ct)
        {
            int studentNo = 0; //local var

            studentNo = 1; //this sets the local var
            this.studentNo = 1; //whereas this sets the class level var
        }
    }

这并不像在类级别的private vars前面加上一个前导下划线那么清楚,因为很容易忘记"this",代码仍然可以编译,但有一个bug.无论如何,建议您不要将local vars作为class level vars的名称,但是使用前导下划线声明class level的倾向会更短地写出"this".

  • public成员是NamedLikeThis,无论是字段(不使用public字段),属性(使用而不是字段),方法等.私有方法似乎没有一个一致的形式,但常见的趋势是使用NamesLikeThis用于类级别的方法,namesLikeThis用于局部函数,这是在其他方法中声明的方法

  • 上面的Gpa也是一个属性,是一个自动,因为编译器为你创建了后备字段(代码中没有private int _gpa),你永远不会看到它或使用它;你只使用属性.如果你想更多地参与到添加代码,例如范围代码,你需要使用StudentNo所采用的完整属性形式,但是当你只需要简单的gat/set行为时,使用auto proeprties可以给你一个干净而简单的方法来编写代码,并将备份字段的创建留给编译器.

  • 不要创建内部类(在另一个类的{ .. }中写入class{ ...}).它是可行的,但经验丰富的开发人员这样做的情况是令人难以置信的有限.保持类作为顶级实体分开,这意味着我建议使用一个完整的代码,看起来像这样(我已经添加了其他建议作为注释):

class Program //typically we keep Main() inside a class called Program
{         
    static void Main(string[] args)
    {
        StudentInfo[] students = new StudentInfo[2]; //collections/arrays have plural names in c#

        students[0] = new StudentInfo(100, 4);
        students[1] = new StudentInfo(101, 3);

        for (int i = 0; i < students.Length; i++) //use array.Length, not hard 2
        {
            Console.WriteLine(students[i].StudentNo);
            Console.WriteLine(students[i].Gpa);
        }
    }
}

class StudentInfo //this class is not declared inside Program/Student
{
    public int StudentNo { get; set; } //i've switched to the auto-property form for clarity

    public int Gpa { get; set;} //Acronyms in C# of 3 or more letters are typically treated as one word in Pascal case, e.g Http, not HTTP
  
    public StudentInfo(int studentNo, int gpa) //name these fully with sensible names, as they will appear in intellisense popups and may appear as named arguments. Nonsense abbreviations make it hard to use the help VS provides and hard to read the code if using named arguments
    {
        StudentNo = studentNo;
        Gpa = gpa;
    }
}

Csharp相关问答推荐

自定义JsonEditor,用于将SON序列化为抽象类

更改对象的旋转方向

HttpContext. RequestAborted当Android APP失go 连接时未取消

编写DataAnnotations自定义验证器的多种方法

如何使用ConcurentDictionary属性上的属性将自定义System.Text.Json JsonConverter应用于该属性的值?

如何注册实现同一接口的多个服务并注入到控制器构造函数中

更新产品但丢失产品ASP.NET Core的形象

自动映射程序在GroupBy之后使用项目

在C#中反序列化/序列化具有混合元素顺序的XML时出现问题

CA1508:';NULL=>;TRUE;始终为';TRUE';.移除或重构条件(S)以避免死代码

EF核心区分大小写的主键

RabbitMQ群集的MassTransit配置问题

如何将%{v_扩展}转换为%{v_扩展}>>

在ObservableCollection上使用[NotifyPropertyChangedFor()]源代码生成器不会更新UI

使用DI实例化带有动态参数的服务?

如何在Cake脚本中设置MSBuild.exe的绝对路径

ASP.NET Core 8 Web API:如何添加版本控制?

嵌套Blazor组件内的验证

缩写的MonthNames有问题

自定义ConsoleForMatter中的DI/Http上下文