Need help with calling one class from another

D

d.s.

I've got an app with two classes, and one class (InventoryInfoClass)
is an object within the other class (InventoryItem). I'm running into
problems with trying to access (get/set) a private variable within the
included class (InventoryInfo) from the "including" class
(InventoryItem).

Here's the code, trimmed down. I've included ********* at the start
of the first line that's blowing up on me. I'm sure others that try
to access the invInfo.companyName field will blow up too.

Any help please?

------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace InventoryInfo
{
public class InventoryInfoClass
{
private string _companyName;


public InventoryInfoClass()
{
companyName = "";

}

public string companyName
{
get
{
return _companyName;
}
set
{
_companyName = value;
}
}

}



public class InventoryItem
{
private InventoryInfoClass invInfo;
private string _itemID;

public InventoryItem()
{
InventoryInfoClass invInfo = new InventoryInfoClass();
_itemID = "";

}

public string itemID
{
get
{
return _itemID;
}
set
{
_itemID = value;
}

}


public string companyName
{
get
{
********* return invInfo.companyName;
}

set
{
invInfo.companyName = value;
}
}


public void printInvItem()
{

Console.WriteLine("Company Name: {0}", this.companyName);
Console.WriteLine("Item ID: {0}", this.itemID);

Console.WriteLine("Press any key to continue");
Console.ReadLine();

}

}


class InvApp
{
static void Main(string[] args)
{
InventoryItem invItem = new InventoryItem();

invItem.printInvItem();

invItem.companyName = "C";

invItem.printInvItem();
}

}

}
 
S

salman

I am feeling that every InventoryItem have an InventoryInfoClass, (or
in other words, every InventoryItem object have a company name) its
means InventoryInfoClass can be a base class for all items.

So you should change your model and inherit InventoryItem from
InventoryInfoClass, then all the private members of InventoryInfoClass
will be accessible in InventoryItem.


Ali


I've got an app with two classes, and one class (InventoryInfoClass)
is an object within the other class (InventoryItem).  I'm running into
problems with trying to access (get/set) a private variable within the
included class (InventoryInfo)  from the "including" class
(InventoryItem).

Here's the code, trimmed down.  I've included ********* at the start
of the first line that's blowing up on me.  I'm sure others that try
to access the invInfo.companyName field will blow up too.

Any help please?

------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace InventoryInfo
{
    public class InventoryInfoClass
    {
        private string _companyName;

        public InventoryInfoClass()
        {
            companyName = "";

        }

        public string companyName
        {
            get
            {
                return _companyName;
            }
            set
            {
                _companyName = value;
            }
        }

    }

    public class InventoryItem
    {
        private InventoryInfoClass invInfo;
        private string _itemID;

        public InventoryItem()
        {
            InventoryInfoClass invInfo = new InventoryInfoClass();
            _itemID = "";

        }

        public string itemID
        {
            get
            {
                return _itemID;
            }
            set
            {
                _itemID = value;
            }

        }

        public string companyName
        {
            get
            {
*********       return invInfo.companyName;
            }

            set
            {
                invInfo.companyName = value;
            }
        }

        public void printInvItem()
        {

            Console.WriteLine("Company Name: {0}", this.companyName);
            Console.WriteLine("Item ID: {0}", this.itemID);

            Console.WriteLine("Press any key to continue");
            Console.ReadLine();

        }

    }

    class InvApp
    {
        static void Main(string[] args)
        {
            InventoryItem invItem = new InventoryItem();

            invItem.printInvItem();

            invItem.companyName = "C";

            invItem.printInvItem();
        }

    }

}
 
G

Göran Andersson

d.s. said:
I've got an app with two classes, and one class (InventoryInfoClass)
is an object within the other class (InventoryItem). I'm running into
problems with trying to access (get/set) a private variable within the
included class (InventoryInfo) from the "including" class
(InventoryItem).

Here's the code, trimmed down. I've included ********* at the start
of the first line that's blowing up on me. I'm sure others that try
to access the invInfo.companyName field will blow up too.

Any help please?

8< snip
public class InventoryItem
{
private InventoryInfoClass invInfo;
private string _itemID;

public InventoryItem()
{
InventoryInfoClass invInfo = new InventoryInfoClass();

Here you have declared a local variable with the same name as the member
variable. The local variable gets assigned the new info object, but the
member variable remains null.
_itemID = "";

}

8< snip
 
D

d.s.

First, the code you posted should work.  The line you say doesn't work  
isn't accessing the private field, but rather a public property.  Can we  
assume that the code you posted isn't in fact the code that you're having 
trouble with?


I agree it should work, but it is bombin on me. It is the code, but
it's trimmed way down, getting rid of other variables and their
accessors.
I admit, from the code you posted, it's not obvious to me why you have the  
nested class anyway.  The outer, containing class is just proxying the  
value to the nested class anyway.  Why not just put that data in the  
containing class?

Ths was a homework assignment. It has already been submitted, so
you're not doing my work for me. But I need to understand what went
wrong because other assignments will build on this. The teacher seems
to be having a bit of a problem responding to requests for help
(online class).

So, the assignment was to do it as done here. The next assignment was
to inherit the InventoryInfo class, which worked with no problems.


That said, the issue you're seeing is a basic rule about nested classes:  
the nested class can see "private" members of the containing class, but  
not the other way around.  That is, since the nested class is effectively  
a member the containing class, it has access to everything _any_ member of  
the containing class would, including all private members of the  
containing class.  But the containing class is most certainly not a member  
of the nested class, and only the members of the nested class can access  
private members.

But it should be able to use the accessors to gain access to the
private variables. Perhaps my terminology is wrong. I'm trying to
use the accessor, and it's blowing up:

********* return invInfo.companyName;


Personally, I don't see the problem here.  I don't know why you want the  
nested class in the first place, but assuming you do, why not just use the  
public property as you've defined it, rather than trying to get at the  
private field?  That's a better encapsulation anyway.

I am trying to use the accessor to gain access to the private field.

********* return invInfo.companyName;

but it doesn't like it.
If you can elaborate on what code is actually not working, and why it is  
you think your containing class should have access to private members of  
the nested class, perhaps we can offer different advice more suitable to  
your goals (assuming the above doesn't do it).

The line I put the asterisks on is the first line that bombs in my
compiler.

If the contained class is to access the elements of the container
class, this means I will need to change the contained class everytime
I want to include it into a different container class that has
different elements.
 
G

Göran Andersson

d.s. said:
I agree it should work, but it is bombin on me.

No, it should not work. Se my other post in the thread.
The line I put the asterisks on is the first line that bombs in my
compiler.

Are you completely sure about that? It compiles just fine for me, but I
get a runtime exception on exactly that line because the invInfo member
variable is null.
 
D

d.s.

No, it should not work. Se my other post in the thread.



Are you completely sure about that? It compiles just fine for me, but I
get a runtime exception on exactly that line because the invInfo member
variable is null.

I'll check that out. The error message I got back was not very
helpful. Yes, it did compile for me. It was a runtime error.
Thanks. I'll check it.
 
D

d.s.

No, it should not work. Se my other post in the thread.



Are you completely sure about that? It compiles just fine for me, but I
get a runtime exception on exactly that line because the invInfo member
variable is null.

I set the invInfo member variable to non-null. And not it blows up on
the set accessor when I try to change it. Also, when I hover over
invInfo on that line, it shows NULL.
 
D

d.s.

I agree it should work, but it is bombin on me.  It is the code, but
it's trimmed way down, getting rid of other variables and their
accessors.  [...]

Ah, I see where I misread.  Your use of the word "including" misdirected  
me and I incorrectly read the "Info" class as being nested.

Also, next time you post a question, please avoid vague terms like "blow  
up" and "bombin [sic] on me".  It doesn't help that one post claims it was  
a compiler error, but more broadly you simply need to post a precise  
description of the error.

Sorry. I was at home, without the code in front of me, and was just
posting from memory.
I apologize for any confusion...as is sometimes the case, trying to answer  
questions very late at night caused me to overlook pretty much all of the 
important parts of the code, relying too much on your description of the  
problem.

You also have a novice over here, to c# anyway.
 
D

d.s.

I agree it should work, but it is bombin on me.  It is the code, but
it's trimmed way down, getting rid of other variables and their
accessors.  [...]

Ah, I see where I misread.  Your use of the word "including" misdirected  
me and I incorrectly read the "Info" class as being nested.

Also, next time you post a question, please avoid vague terms like "blow  
up" and "bombin [sic] on me".  It doesn't help that one post claims it was  
a compiler error, but more broadly you simply need to post a precise  
description of the error.

Ok, I just compiled and ran the code here at work.

It gives me a run-time error on that line with a message of "Object
reference not set to an instance of an object." If I hover over
invInfo, it shows NULL.

So, within that accessor, it can't see the instance of invInfo that I
created in the constructor.

I tried changing the scope (or whatever you call it) of invInfo from
private to protected. Same problem. I set the companyName to "test"
in the constructor. Same problem.

I'm using VS 2008 on this. It's a console app.

I'm going to reread Goran's post, to make sure I got it all.
 
D

d.s.

8< snip





Here you have declared a local variable with the same name as the member
variable. The local variable gets assigned the new info object, but the
member variable remains null.

Ok, I'm a little vague on this. Not that you're vague. I'm just not
sure how to set this up. I thought by doing the following, I was
setting up a local variable:


public class InventoryItem
{private string _itemID;
 
D

d.s.

Ok, I'm a little vague on this.  Not that you're vague.  I'm just not
sure how to set this up.  I thought by doing the following, I was
setting up a local variable:

 public class InventoryItem
    {>>>>public InventoryInfoClass invInfo;

        private string _itemID;- Hide quoted text -

- Show quoted text -

I'm stepping through this code, and, in the constructor, I can see the
instance of invInfo populated. When I leave the constructor, invInfo
is null. I thought the constructor creates a persisting instance.
 
D

d.s.

The constructor is just another method.  It doesn't have any magic to  
cause an instance to persist unless you copy the reference to that  
instance somewhere that will make it persist.

That worked. Thanks Peter, and Goran, and all. I thought I would
have needed to cast or define that variable before I assigned an
object to it.

I'm not new to programming, but I am new to conceptualizing all the
ins and outs of scoping and instantiation in object oriented
programming. It doesn't always stick very well in the wetware.

Thanks again.
 
D

d.s.

Casting, no.  Define a variable, yes.  But you already did, as the  
instance field from which you try to retrieve it later.  The local  
variable was superfluous.

Glad it worked out.  :)

Ok, I think I got it. I inadvertently created a separate instance of
invInfo within the constructor, which only had scope within the
constructor, rather than referencing the class variable.

Is that it?

Thanks.
 
G

Göran Andersson

d.s. said:
Ok, I'm a little vague on this. Not that you're vague. I'm just not
sure how to set this up. I thought by doing the following, I was
setting up a local variable:


public class InventoryItem
{
private string _itemID;

No, that's a member variable. It's scope is the class.

A local variable is a variable declared inside a method, and it has the
scope of that method.

You dceclared a local variable in the constructor with the same name as
the member variable. You created an instance of the class (using the new
keyword), and assigned it's reference to the local variable.

When the constructor code ends, the local variable goes away, and with
it the reference to the instance that you created.

As you want to access the member variable, you should not create the
local variable at all.

Change this:

InventoryInfoClass invInfo = new InventoryInfoClass();

to:

invInfo = new InventoryInfoClass();
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top