首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >理解对象范围的基本原理

理解对象范围的基本原理
EN

Stack Overflow用户
提问于 2015-04-22 21:24:34
回答 4查看 174关注 0票数 1

对于对象,我有一个基本的块:当您创建一个“新”对象时,它会替换以前的对象。如果这是真的,那么将对象创建放在哪里,这样它就不会在一个重复的调用中被替换,比如while或For循环?

我正在阅读一本C#书籍,并试图使用多维数组作为我的表来创建地址簿。我的问题是,每次创建"New“数组时,先前的数据都会丢失.:-(

如果我将Addressbook对象移动到另一个位置,程序的其余部分将找不到它。所有关于面向对象设计的书都让我感到困惑和沮丧。希望你能弄清楚我的想法出了什么问题。这是我的节目:

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class Addressbook
{
    public string[,] fullname;
    public int cnt;
}

namespace ConsoleApp
{
    class MethodParams
    {
        public static void Main()
        {
            string myChoice;

            MethodParams mp = new MethodParams();
            do
            {                                
                // show menu and get input from user
                myChoice = mp.getChoice();

                // Make a decision based on the user's choice
                mp.makeDecision(myChoice);

                // Pause to allow the user to see the results
                Console.Write("press Enter key to continue...");
                Console.ReadLine();
                Console.WriteLine();
            } while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit
        }
//*******************
        // show menu and get user's choice
        string getChoice()
        {
            string myChoice;
            // Print A Menu
            Console.WriteLine("My Address Book\n");
            Console.WriteLine("A - Add New Address");
            Console.WriteLine("D - Delete Address");
            Console.WriteLine("M - Modify Address");
            Console.WriteLine("V - View Addresses");
            Console.WriteLine("Q - Quit\n");
            Console.WriteLine("Choice (A,D,M,V,or Q): ");
            // Retrieve the user's choice
            myChoice = Console.ReadLine();
            return myChoice;
        }
//***********************
        // make decision
        void makeDecision(string myChoice)
        {
            Addressbook addrBk = new Addressbook();  //Create Addressbook Object
            addrBk.fullname = new string[10, 10];
            addrBk.fullname[0, 0] = "Tom";
            addrBk.fullname[0, 1] = "Nesler";
            addrBk.cnt = 1;
            switch (myChoice)
            {
                case "A":
                case "a":
                    Console.WriteLine("Enter First name");
            String FName;
                    FName =  Console.ReadLine();
            Console.WriteLine("Enter Last name");
                    String LName;
                    LName =  Console.ReadLine();
                    addrBk.fullname[addrBk.cnt,0] = FName;
                    addrBk.fullname[addrBk.cnt,1] = LName;
                    this.addAddress(ref addrBk);        //Input address name
                    addrBk.cnt = addrBk.cnt + 1;
                    break;

                case "V":
                case "v":
                    this.viewAddresses(ref addrBk);
                    break;
                case "Q":
                case "q":
                    Console.WriteLine("Bye.");
                    break;
                default:
                    Console.WriteLine("{0} is not a valid choice", myChoice);
                    break;
            }
        }
//*****************
        // insert an address
        void addAddress(ref Addressbook addrBk)  //Addr Object containing name and Address
        {
            Console.WriteLine("Name: {0} {1} added.", addrBk.fullname[addrBk.cnt, 0], addrBk.fullname[addrBk.cnt, 1]);
        }
//*****************
        // show addresses
        void viewAddresses(ref Addressbook addrBk)
        {
            Console.WriteLine("count is: {0}", addrBk.cnt);
           for (int i=0; i < addrBk.cnt; i++) 
            {
               Console.WriteLine("counter = {0}",i );
               Console.WriteLine("Name: {0} {1} ", addrBk.fullname[i,0], addrBk.fullname[i,1] );
            }
        }
    }

}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-22 22:13:51

您可能会感到困惑的事情之一与成员变量有关。基本思想之一是,对象封装其操作的数据和方法。这意味着,该数据对于对象中的所有方法都是可用的,而不必作为该方法的参数提供。此数据存储在成员变量中。

以您的AddressBook为例,您可以看到它只有数据成员(fullnamecnt),但是没有方法。不过,您的程序确实在一个通讯簿上执行几个操作,比如addAddress向其添加一个地址,viewAddresses在控制台上显示地址簿中的所有地址。

对于一个类来说,典型的是它同时包含数据和方法。因此,在您的情况下(只需移动一些现有代码,并应用一些惯用的c# tweeks来命名):

代码语言:javascript
运行
复制
public class Addressbook
{
    private string[,] _fullname;
    private int _cnt;

    public Addressbook()
    {
       // Questions:
       // Are 10 fields really needed for firstName and lastName?
       // What if a user adds more than 10 names.
        _fullname = new string[10, 10]; 
    }

    public void AddAddress(string firstName, string lastName)
    {
        _fullname[_cnt,0] = firstName;
        _fullname[_cnt,1] = lastName;
        Console.WriteLine("Name: {0} {1} added.", _fullname[_cnt, 0], _fullname[_cnt, 1]);
        _cnt = _cnt + 1;
    }

    public void ViewAddresses()
    {
        Console.WriteLine("count is: {0}", _cnt);
        for (int i=0; i < _cnt; i++) 
        {
           Console.WriteLine("counter = {0}",i );
           Console.WriteLine("Name: {0} {1} ", _fullname[i,0], _fullname[i,1] );
        }
    }
}

AddressBook类现在可以做它以前能做的一切,现在MethodParams可以使用它,而不需要确切地知道 AddressBook是如何完成它的工作的。它只需要知道可以做什么。

现在,如果我们稍微修改一下class MethodParams,以便给它一个通讯录以供使用,事情就变得容易得多了:

代码语言:javascript
运行
复制
class MethodParams
{
    private AddressBook _addressBook;

    public MethodParams(AddressBook addressBook)
    {
        _addressBook = addressBook; // this is the address book we will work with
    }

    public static void Main()
    {
        string myChoice;
        AddressBook theAddressBook = new AddressBook();

        MethodParams mp = new MethodParams(theAddressBook);
        do
        {                      
             // ... this can all stay the same.          
        } while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit

        // When we get here, theAddressBook still contains everything.
        // We could save it to a file.
    }

    // ... see remarks for changes below.
}

现在,在您的makeDecision方法中,您可以执行以下操作来添加一个地址:

代码语言:javascript
运行
复制
_addressBook.AddAddress(FName, LName);

这个可以查看所有地址。

代码语言:javascript
运行
复制
_addressBook.ViewAddresses();

我希望这有助于澄清几件事。以下是你在评论中提出的一些问题的答案:

这一行public class Addressbook启动的定义,它是类型的,就像string是类型一样。

这一行private AddressBook _addressBook;声明了一个名为_addressBook的私有成员变量,该变量的类型为AddressBook,属于MethodParams类。

在这一行AddressBook theAddressBook = new AddressBook();中,我们创建了一个类型为AddressBook的新的对象实例,它被分配给带有名称theAddressBook的局部变量。

在这一行MethodParams mp = new MethodParams(theAddressBook);中,我们创建了一个新的MethodParams类型的对象实例,并通过它的构造函数方法public MethodParams(AddressBook addressBook)对其进行初始化,将其作为方法参数E 246命名为addressBook的对象实例theAddressBook作为方法参数的引用。

在这一行_addressBook = addressBook中,作为addressBook提供给构造函数的值(它是对我们前面在代码中创建的theAddressBook对象实例的引用)分配给名为_addressBook的私有成员变量。现在,当MethodParams中的任何方法使用_addressBook时,例如,像这样的_addressBook.AddAddress(FName, LName),它们都在使用我们创建的对象实例theAddressBook

票数 0
EN

Stack Overflow用户

发布于 2015-04-22 21:55:59

代码语言:javascript
运行
复制
string a;   // this is a declaration - the variable `a` is null/nothing until 
            // you assign it a value

a = new String("Hello world");  // the variable `a` now references a String 
                                // Object that contains the string "Hello world"

a = new String("Good-bye World");  // the variable `a` now references a String 
                                   // Object that contains the string "Good-bye World" 

这是一个如何丢失对象的例子。在“旧时代”,这被称为记忆泄漏。在当今的托管代码世界中,丢失的对象被“垃圾收集”所捕获。

当您实例化和对象时,通常会将其传递给一些类似对象的集合,以供以后参考。也许是一个列表(地址)或字典(字符串,地址)。这是对象“存在”的地方,直到集合本身超出范围。

在您的程序中,所有这些代码都有一个有限的生命周期,即代码的运行时间。当程序结束时,这是对象生命周期的最终作用域。这就是为什么我们有类似于数据库的东西,这样我们就可以保存和恢复我们用编程语言创建的思想。

票数 0
EN

Stack Overflow用户

发布于 2015-04-22 21:59:24

我假设您希望创建并更新您的addrBk,因此在您的示例中有几个选项。首先,您可以在Main方法中创建对象,然后将其传递给makeDecision方法:

代码语言:javascript
运行
复制
public static void Main()
{
///...
    Addressbook addrBk = new Addressbook();
    addrBk.fullname = new string[10, 10];
    addrBk.fullname[0, 0] = "Tom";
    addrBk.fullname[0, 1] = "Nesler";
    addrBk.cnt = 1;

    do
    {
        // rest of code
        mp.makeDecision(addrBk, myChoice);
        // rest of code
    } //while ...
}
    void makeDecision(Addressbook addrBk, string myChoice)
    {
        switch (myChoice)
        //rest of code...
    }

您还可以在类中创建静态对象,然后像在示例中一样使用它,您可能不需要创建多个对象。还可以检查其他fnostro的答案,因为它可能会让您更好地理解基本面。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29809144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档