【问题标题】:C# need to pass an object so another class can call it's methods to update itC# 需要传递一个对象,以便另一个类可以调用它的方法来更新它
【发布时间】:2011-05-25 10:39:25
【问题描述】:

我有一堂课,里面有 3 个公共列表。它基本上只是一个数据保存类。

我有一个带有 xml 的文件,例如分隔符(某种类型的乞求和结束标签,以及介于两者之间的数据值)

我有一个解析类,它检测数据保存类中的某些内容并将其添加到某些列表中。基本上我正在尝试检测一个开始标签,将它存储在我的数据保存类的开始标签列表中。

我试图走的路(基于教师糟糕的借口举个例子)是 Main() 将数据保存类实例化为一个对象,同样适用于解析类。然后它调用 ParseMain 来解析文件并将标签、数据值和结束标签分离到数据保存类中它们各自的 List 中。然后在 Parse 类完成后,回到 main,我正在调用数据类中的方法来显示数据。

我基本上被编译器骂了,因为即使 xml 数据持有者类已经在 main 中实例化,它也没有或不能添加到公共列表中,我特别得到了这个错误

“非静态字段、方法或属性需要对象引用”

如何从我的解析类中设置数据读取类列表?

我的老师举了一个可怕的例子(除了标记为静态的类,他什么都有,基本上只是将 java/c++ 样式的代码拍成几个类)

这是我学习的一个基本编程课程的所有额外功劳。(普通版本都是在一个类中的结构)

***编辑-添加代码sn-ps

                    XMLDoc XMLData = new XMLDoc();
                    XMLParse parseXML1 = new XMLParse();


                    //Calls the parseXML1 method passing it
                    //the name of the currently opened file.
                    parseXML1.MainParse(fileIn);

然后到我的主要解析

    public void MainParse(FileStream fileIn)
    {

        int byteIn;


        while ((byteIn = fileIn.ReadByte()) != -1)
        {

            if (byteIn == '<')
            {
                ParseElement(ref byteIn,fileIn);
            }

ParseElement 看起来像

    public void ParseElement(ref int byteIn,FileStream fileIn)
    {
        token += byteIn;
        //First I need to get the entire tag stored in token
        do
        {        
            byteIn = fileIn.ReadByte();
            token += byteIn;
        } while (byteIn != '>');
        token += '>';

        //now I insert a / into my compare token
        compareToken = token;
        compareToken.Insert(1,"/");

        //It's an ending tag
        if (token == compareToken)
        {
            //figure this out later
        }
        //It's an opening tag,store it into element list
        else
        {
            XMLDoc.elements.Add(token);
            //also tried XMLData/elements/Add(token)
        }

    }

最后我的 XMLDoc 类看起来像......

class XMLDoc
{
    public List<string> elements;
    public List<string> dataValues;
    public List<string> endingElements;

    public XMLDoc()
    {
        elements = new List<string>();
        dataValues = new List<string>();
        endingElements = new List<string>();
    }

    //This method simply displays the contents of the arrays
    public void DisplayCollected()
    {
        Console.WriteLine("Begin unformatted dump");
        for (int ii = 0; ii <= elements.Count;ii++)
        {
            Console.WriteLine("\n"+elements[ii]+dataValues[ii]+
                "\n"+endingElements[ii]);
        }
        Console.WriteLine("End unformatted dump\n");
    }

    //This method will generate an xml style display
    //To add later

}

我在玩,边做边学等等。在这一点上,我不得不放弃教师的例子,如上所述,他只是将每个班级中的每个方法都设为静态,可能是因为他将他的例子从主要实验室工作(这是结构性的,全部在第一堂课中)拍打在一起

【问题讨论】:

  • 发布代码的相关部分比描述它的工作原理要有效得多——尽管描述也很好。
  • 我现在就添加,但是太草率了。
  • 马虎与否,不看代码很难有效回答。

标签: c# arrays properties


【解决方案1】:

编辑:好的,看起来您只需将引用传递给周围的对象,例如

XmlDoc xmlData = new XmlDoc();
XmlParser parser = new XmlParser();
parser.MainParse(xmlData, fileIn)

...

public void MainParse(XmlDoc xmlData, FileStream fileIn)
{
    ...
    ParseElement(xmlData, ref byteIn, fileIn);
    ...
}

public void ParseElement(XmlDoc xmlData, ref int byteIn,FileStream fileIn)
{
    ...
}

我稍微调整了名称以更符合 IMO。

顺便说一下,我建议您不要XmlDoc 中使用公共字段。公共字段违反封装 - 如果您确实需要公开值,则使用属性,但理想情况下将更多行为放在对象本身中。

【讨论】:

  • 属性无法使用 3 个不同的列表。如果我有 1 个列表,我只能使用一个属性。我本可以为每个人做一个获取和设置的实际方法,但实际上在一天结束时,这个程序中的任何数据实际上都不需要封装(它最初是在主类中为实验室编写的,而不是OOP)——我的挫败感让我说“去他妈的,我已经结束了这场斗争,它要公开了!”大声笑-非常感谢您的帮助
  • @Tyler:为什么不能拥有三个不同的属性?
  • @Tyler,你似乎误解了我之前的回答。 如果您想要控制列表中的内容,您只能不使用列表的属性。如果您对您班级的客户向/从列表中添加/删除项目感到高兴(或完全替换列表,那么属性就可以了。如果您希望能够在添加项目之前对其进行审查,或者做其他一些事情添加/删除/更改某些内容时的逻辑,然后您不能公开列表,无论是作为字段还是通过属性。PS,您应该开始接受一些问题的答案
  • 据我了解,由于索引器的定义方式,我实际上无法将属性 (get;set;) 与数组或 list 一起使用。这样,说 list a;和列表 b;属于同一类,但数组和列表的属性是 public list this[ii] {get;set;} --
  • @Tyler:不,完全可以将属性与数组和列表一起使用。没有人说您必须使用索引器 - 您可以编写一个返回列表的属性。
【解决方案2】:

这里的错误信息很不错:“非静态字段、方法或属性需要对象引用”

您正在尝试以静态方式调用实例方法,您有两种选择:

  1. 将方法设为静态。
  2. 实例化类并从实例调用方法。

例如:

public class Foo()
{
    public void Frob() {}
}

你不能这样做:

Foo.Frob();

但你可以这样做:

var foo = new Foo();
foo.Frob();

或者这个:

public class Foo()
{
    public static void Frob() {} // Note static
}

[...]

Foo.Frob();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-21
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多