如何为不同类的字段赋值?

Posted

技术标签:

【中文标题】如何为不同类的字段赋值?【英文标题】:How to assign a value to a field in different class? 【发布时间】:2019-03-23 19:31:58 【问题描述】:

在这个程序中,我有 2 个类 Application 和 Customer。我想用用户输入的一些值来初始化标准票价。标准票价字段位于客户类中。 我这样做了,但它没有显示出预期的结果。当调用Calculate函数时,标准票价的价值变为零。

当我在 Customer 类本身中初始化 STANDARD_FARE 的值时,程序会按预期工作。 如何输入用户给 STANDARD_FARE 的值?

Application 类中的 GetAge()、GetPassNo() 等方法也不会返回相同的值。

 class Application
  
    private static int Nop ;
    private static double TotalFare=0;
    Customer cust= new Customer(); 

    static void Main(string[] args)
      
        Application obj = new Application();                      
        Console.Write("Enter the STANDARD RATE of the tour ");
        obj.cust.StandardFare = int.Parse(Console.ReadLine());

        a:
        Console.Clear();                                             
        Console.WriteLine("Enter the number of passengers");
        Nop = int.Parse(Console.ReadLine());                       

        Application[] app = new Application[Nop];                 

        if (Nop <= 0)                                               
        
            Console.WriteLine("Please enter a valid number of passengers");
            Console.ReadKey();                                     
            goto a;
        

        for (int i = 0; i < Nop; i++)
        
            app[i] = new Application();                           
            app[i].GetInformationFromCust();         
        

        for (int j = 0; j < Nop; j++)
        

           app[j].cust.Display();                                  

                                                    
     

    public int GetInformationFromCust()
          
         b:
        Console.Clear();                                     
        int slen = 0;                                   

        Console.WriteLine("Enter the title of the passenger");
        cust.Customer_Title = Console.ReadLine();
        Console.WriteLine("\r\nEnter passenger's First name :");
        cust.Customer_FName = Console.ReadLine();
        Console.WriteLine("\r\nEnter passenger's Last name :");
        cust.Customer_LName = Console.ReadLine();
        slen = cust.Customer_FName.Length + cust.Customer_LName.Length;    
         if (slen < 5 || slen > 15)                                       
          
            Console.WriteLine("\r\nName should be between 5 to 15 characters, Please try again ");
            Console.ReadLine();
            goto b;
          

        c:
        long x = 0, len = 0;
        Console.WriteLine("\r\nEnter the passport number of the passenger ");
        cust.CustomerPassNo = int.Parse(Console.ReadLine());
        x = cust.CustomerPassNo;               

         while (x > 0)
          
            x = x / 10;                    
            ++len;
          
        if (len != 8)                    
          
            Console.WriteLine("\r\nInvalid passport number, passport should be of 8 digits ");
            goto c;
          

        d:
        Console.WriteLine("\r\nEnter the age of the passenger :");
        cust.Customer_Age = int.Parse(Console.ReadLine());
          if (cust.Customer_Age < 0)                                         
          
             Console.WriteLine("\r\nInvalid age, please enter a valid age ");
             goto d;
           
        cust.CalculatePrice();                                          
        return 0;
    

    public int GetAge()
    
        return cust.Customer_Age;
    

    public double GetAirFare()
    
        return cust.CustomerTicket ;
    

    public long GetPassportNo()
    
        return cust.CustomerPassNo;
    

    public string GetTitle()
    
        return cust.Customer_Title;
    
 
class Customer 
  
    const double K_DISCOUNT = 0.10;                            
    const double S_DISCOUNT = 0.20;

    private double STANDARD_FARE;
    private string CustomerName  get; set; 
    private int CustomerAge;
    private string CustomerFName;
    private string CustomerLName;
    private long CustomerPassport;
    private double CustomerPrice; 
    private string CustomerTitle;
    private double KidDiscount;
    private double SeniorDiscount;

    public Customer()                                         
    
        this.KidDiscount = K_DISCOUNT;
        this.SeniorDiscount = S_DISCOUNT;
    

    public double StandardFare
    
        get  return STANDARD_FARE; 
        set  STANDARD_FARE = value; 
    

    public int Customer_Age
    
        get  return CustomerAge; 
        set  CustomerAge = value; 
    

    public string Customer_Title
    
        get  return CustomerTitle; 
        set  CustomerTitle = value; 
    

    public string Customer_FName
    
        get  return CustomerFName; 
        set  CustomerFName = value; 
    

    public string Customer_LName
    
        get  return CustomerLName; 
        set  CustomerLName = value; 
    

    public long CustomerPassNo
    
        get  return CustomerPassport; 
        set  CustomerPassport = value; 
    

    public double CustomerTicket
    
        get  return CustomerPrice; 
        set  CustomerPrice = value; 
    


    public int CalculatePrice()
    
        if (CustomerAge < 3)
        
            CustomerPrice = 0;
        
        else if (CustomerAge >= 3 && CustomerAge < 18)
        
            CustomerPrice = STANDARD_FARE - (STANDARD_FARE * KidDiscount);
        
        else if (CustomerAge > 65)
        
            CustomerPrice = STANDARD_FARE - (STANDARD_FARE * SeniorDiscount);
        
        else
        
            CustomerPrice = STANDARD_FARE;
        
        return 0;
    

    public void Display()
    
      //some code here
    

【问题讨论】:

我强烈建议您不要使用goto。只需使用 do-while 循环即可。 您已经在此处设置了标准票价:obj.cust.StandardFare = int.Parse(Console.ReadLine());。您只需需要确保然后您还使用了 same Application 和 Customer 对象,您确实在其上设置了来自用户输入的值。如果您查看 other Customer 对象,那么您当然不会找到用户输入的值... 为什么要在GetInformationFromCust中新建一个Application对象? 我正在使用对象数组来获取多个乘客的数据。 如何使用该对象来初始化 STANDARD FARE。 【参考方案1】:

您正在使用仍具有默认 STANDARD_FARE 值(即 0.0)的 Application 实例填充数组 app,因为 您从未在这些实例上设置它。您将其设置在obj.cust 实例上,您将不再使用该实例。因为STANDARD_FARE 是一个实例变量,所以对它的更改不会影响其他(或未来的)实例。

使用所有Application.Get* 函数,您也会遇到同样的问题;他们正在获取一个从未设置过任何属性的对象 (obj.cust) 的属性,除了 StandardFare/STANDARD_FARE

最明显的解决方法是完全取消objobj.cust - 除了令人困惑之外,它们没有任何用处 - 并且STANDARD_FARE 设为静态变量(及其设置器 StandardFare 一个静态属性)。


顺便说一句,您的命名约定很糟糕且不一致;如果我是你的评分员,我会因为使用不明确的变量名(appnop)和将 ALL_CAPS 用于非常数(STANDARD_FARE)而扣分。我还反对使用私有的自动支持属性(CustomerName,它也从未使用过)而不是简单的私有变量,因为 not 在其他地方使用自动支持的属性(StandardFare作为STANDARD_FARE 等的显式编码的公共getter 和setter),以及将常量值复制到不可设置的实例变量中(K_DISCOUNTKidDiscount;只需直接使用常量,或者至少使@987654342 @static 并添加一些非私人访问)。正如其他人所提到的,您当然不应该使用 goto 代替循环。我还将提到通过重复除法而不是简单地检查它是否小于 99999999 来检查护照号码的长度容易出错且效率低下(理论上,护照号码可能以零开头,看起来小于 8 位解析后,但如果你愿意,你也可以确保它大于10000000)。

【讨论】:

谢谢,我将 STANDARD_FARE 及其属性设为静态,现在一切正常。正如您提到的,我还删除了 Application 类的 obj 对象。由于这不是我的最终代码,因此命名存在一些我没有更正的问题。 1) STANDARD_FARE 全部大写,因为在我已经定义了它的值之前。但是现在我希望从用户那里获取 STANDARD_FARE 的值,所以我现在没有更改它,但我稍后会更改,2) app = 类应用程序的对象,Nop = 乘客人数。 3) 我现在更正了 CustomerName 的问题,这完全是因为我之前在代码中做了其他事情。 4) 在我的问题中,有人提到我应该使用常量值以及名为 KidDiscound 和 SeniorDiscount 的字段。因此,我在那里做了那些不专业的事情来满足问题要求 5) 好的,我将用其他一些逻辑替换所有使用的 goto。还有那个护照号码检查逻辑。谢谢您的帮助。荣誉

以上是关于如何为不同类的字段赋值?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 如何为同类用户数据创建基于Webix的多行输入

应该如何为具有不同字段的几个猫鼬模型创建模式?

如何为不同的请求建模不同类型的表单

如何为每个循环发出不同的元组并在风暴螺栓的单个字段方法中声明?

如何为 RadioButton 赋值

如何为graphql类型的字段对象添加排序,引用不同的graphql类型?