Passing an object to another class? - c#

I've recently been looking into constructors, Im currently trying to pass a object to another class file, The way im doing it is like this:
class Program
{
static void Main(string[] args)
{
Class1 objPls = new Class1();
objPls.nameArray[0] = "jake";
objPls.nameArray[1] = "tom";
objPls.nameArray[2] = "mark";
objPls.nameArray[3] = "ryan";
Echodata form2 = new Echodata(objPls);
}
}
class Class1
{
public string[] nameArray = new string[3];
}
class Echodata
{
public Class1 newobject = new Class1();
public Echodata(Class1 temp)
{
this.newobject = temp;
}
// so now why cant i access newobject.namearray[0] for example?
}
Problem is i cant access the object to get into the array..
What methods of passing objects are there? I was told this is roughly a way to do it and have been experimenting for a while to no avail.

Not sure what it is you cannot do. For example your code with this modification works, or at least compiles.
class echodata
{
public Class1 newobject = new Class1();
public echodata(Class1 temp)
{
this.newobject = temp;
}
// so now why cant i access newobject.namearray[0] for example?
// What kind of access do you want?
public void method1()
{
newobject.nameArray[0] = "Jerry";
}
}

You have an issue where your code will throw an error when trying to set the "ryan" string on the fourth index of the array. You initially set the array to be of length 3.
In your EchoData class you can access the nameArray object without an issue but you must be accessing it within a method or in the constructor. You cannot be manipulating it's content outside of these.
Keep in mind that within your EchoData class you will not see the values you set inside of your Main method.

It's hard to tell since you haven't included a complete, compilable sample, and you haven't explained exactly what "can't access" means (do you get an error? what is it?)
However, my guess is that you are attempting to access the passed in objects fields from the class level based on your code.
ie, you are trying to do this:
class Echodata
{
public Class1 newobject; // you don't need to initialize this
public Echodata(Class1 temp)
{
this.newobject = temp;
}
newobject.newArray[0] = "Can't do this at the class level";
}
You can only access nameArray from within a member method.
class Echodata
{
public Class1 newobject; // you don't need to initialize this
public Echodata(Class1 temp)
{
this.newobject = temp;
}
public void DoSOmething() {
newobject.newArray[0] = "This works just fine";
}
}

Related

I can't get value of base class field from child class object in c#

using System;
public class Program
{
public static void Main()
{
CloudCollectionHelper cloudHelper = new CloudCollectionHelper();
SlackHelper slackHelper = new SlackHelper();
cloudHelper.DatabaseID=12345;
Console.WriteLine(slackHelper.GetSlackPageTokens());
}
class CloudCollectionHelper
{
public long DatabaseID { get; set; }
}
class SlackHelper:CloudCollectionHelper
{
public long GetSlackPageTokens()
{
return DatabaseID;
}
}
}
current output: 0
Expected Output: 12345
I need output 12345 because DatabaseID from the cloudhelper so i need that databaseID in the slackhelper.
this is my c# online compiler: https://dotnetfiddle.net/QNQeEX
The child class does not get the assigned values from the base class. Becouse there can be mutliple instances from it. For example, if you have
...
CloudCollectionHelper cloudHelper1 = new CloudCollectionHelper();
CloudCollectionHelper cloudHelper2 = new CloudCollectionHelper();
cloudHelper1.DatabaseID = 1234;
cloudHelper2.DatabaseID = 6789;
Console.WriteLine(slackHelper.GetSlackPageTokens()); //It would not know, what value to use.
...
The best way would be assigning the value directly to the child class or using the static modifier.
Edit:
Best way if you need to take this value from the child class for whatever reason would be doing something like this:
...
CloudCollectionHelper cloudHelper = new CloudCollectionHelper();
cloudHelper.DatabaseID = 12345; //First assign the needed Value
SlackHelper slackHelper = new SlackHelper(cloudHelper); //then create a new instance from the child class
...
and add the constructor from the SlackHelper child class like this:
class SlackHelper:CloudCollectionHelper
{
public SlackHelper(CloudCollectionHelper cloudHelper)
{
this.DatabaseID = cloudHelper.DatabaseID;
}
... //Do everything else what this class needs here
}
If the Value from cloudHelper.DatabaseID can update during the runtime, you will need a event to update the child class. It still isn't the best way to do this, because the DatabaseID value is already public and can be accessed without the child class.
Edit 2:
Like I already told you in the comments, you could also avoid this problem with the static modifier. But this will effect every instance made from the CloudCollectionHelper class. As soons as you make it static, this will only hold 1 possible value for all instances.
(Please keep in your mind to use a comment if needed or best case, just avoid Magic numbers)
The property of your Object slackhelper has not been affected.
You don't need to create a CloudCollectionHelper Object.
SlackHelper slackHelper = new SlackHelper();
slackHelper.DatabaseID=12345;
Console.WriteLine(slackHelper.GetSlackPageTokens());
You should create this property inside the class to allow to read the Database ID
public long GetSlackPageTokens()
{
return base.DatabaseID;
}

Filling and printing out an array of class type

Okay, so I'm not very good with explaining, but basically i have a simple class - let's say something like this:
class Dog
{
public String Name { get; set; }
public String Breed { get; set; }
}
Then I have this other class:
static class DogData
{
static public Dog[] Dogs
{
get
{
//Dog[] Dogs = new Dog[2]; - unnecessary, as pointed out by helpful Samaritans
ResetDogData();
return _dogs;
}
set { }
}
static public Dog[] _dogs;
static private void ResetDogData()
{
Dog[] _dogs = new Dog[2];
if (_dogs[0] == null)
{
_dogs[0] = new Dog();
_dogs[0].Name = "Johny";
_dogs[0].Breed = "German Shepard";
}
if (_dogs[1] == null)
{
_dogs[1] = new Dog();
_dogs[1].Name = "Sally";
_dogs[1].Breed = "Alaskan Malamute";
}
}
The idea was to have the Dogs array being filled with input from the console, and if the array element
is null - to get its data from the ResetDogData(). But before trying to do this, i wanted to test
if the ResetDogData() even works.
And here's the thing - every time i try to print it out, i either get 'Object reference not set to an instance of an object' or, if it compiles, simply nothing prints out (depending on what way i tried doing it). So I was wondering if my code is totally wrong or I am simply missing some of the basics of working with arrays (e.g. my mistake is the way I am trying to print out the array).
I'd be really grateful if someone can tell me which of the two is it, and what is the right way to achieve what i want.
ResetDogData is not modifying the class-level _dogs member - is it creating a local _dogs variable, populating it, and then doing nothing with it.
To reset the class member's data, change
Dog[] _dogs = new Dog[2];
to
_dogs = new Dog[2];
within ResetDogData
also, you can get rid of the ifa, since the newly-created array will always be initialized with null:
static private void ResetDogData()
{
_dogs = new Dog[2];
_dogs[0] = new Dog();
_dogs[0].Name = "Johny";
_dogs[0].Breed = "German Shepard";
_dogs[1] = new Dog();
_dogs[1].Name = "Sally";
_dogs[1].Breed = "Alaskan Malamute";
}

How to access a property of an object within an object C#

I'm trying to make a code that reads the object property of an object before using said ability. In this case, it reads the cooldown of the the ability, then casts the ability if the cooldown equals zero. However, I can't get the code to run without experiencing an error. It will not let me access the property.
public class Pug : Dogs
{
public Pug()
{
ability bark = new Ability();
bark.cooldown = 2;
}
public void PugBark()
{
if (bark.cooldown == 0)//error occurs on this line
{
//He Barks
}
}
}
because of your bark object the only available in the construct function scope.
I think you can try to let bark be a field or property in the Pug class
public class Pug : Dogs , ThingsDogsDo
{
private Ability bark;
public Pug()
{
bark = new Ability();
bark.cooldown = 2;
}
public void PugBark()
{
if (bark.cooldown == 0)//error occurs on this line
{
//He Barks
}
}
}

Dot notation for class member access

I've got the following code:
public class Random
{
public string Name { get; set; }
public bool IsRunning()
{
var running = true;
return running;
}
}
public class Main
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
which all exists in the same .cs file in the same namespace. Any time I've created a new project before I've never had to set up anything to use dot notation to access member attributes or methods, but this is saying that I can't use newObject. ANYTHING, and also that "var" is not valid for a keyword. It's a windows forms application like I normally use, but I'm drawing blanks here as why I can't do all these things that I normally use many times in my other programs. What am I missing here?
You're trying to write code directly within the class declaration. A class declaration can only directly contain member declarations. It can't contain arbitrary statements such as newObject.Name = "Johnny" nor can it use var, which is only applicable to local variables. If you put the code in a method, it should be absolutely fine. For example:
public class Main
{
public void DoSomething()
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
}
As an aside, I'd strongly recommend against naming your own class Random given that that's also the name of a class within the System namespace.
You cannot use var or assign values to some other object within a class member definition.
You code in public class Main is not within a method.
I guess what you were trying to do is writing a Console app and that needs a
public static void Main()
method
so change your class to e.g.
class Program
{
static void Main(string[] args)
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
}

C# Struct / Lookup Table

Say I have a struct declared like the following:
public struct Test
{
public static int Width = 5;
...
public static int[] Value = new int[1]{ 0 };
}
Now what I want to do is call this from within another struct, but I have to clue how. What I'm trying to do would (in my mind) look like the following:
public struct AnotherStruct
{
public (type of struct) this[int key]
{
get
{
switch(key)
{
case 1:
return (another struct);
default:
return null;
}
}
}
}
My end goal is that I want to use code that looks like the following, without having to create an instance of the object:
structobject s = new AnotherStruct[5];
So this 'lookup table' will be created in another project and built, then called as a dll from my main project. Since I'm building the dll elsewhere and calling it, I'm hoping that I can get the dll loaded into memory once, and then I can just reference that memory from my main project. Then I'll have one allocated portion of memory and my code will just reference it, avoiding the need to create individual instances of this lookup table (thus avoiding the time overhead it takes to allocate the memory and store the new instance). The time I'd save would be hugely beneficial in the long run, so I'm hoping I can get this to work somehow.
I hope this isn't too confusing, but let me know if any clarification is needed.
Edit
This is being used on a website, so really I need an object that persists across all connections and is created once when the code is initially loaded. Same idea, but maybe that will make for a simpler solution?
Solution #2. Forgo the whole ID idea and just use the structure type and generics.
public struct St1
{
}
public struct St2
{
}
public class Factory<T>
where T : struct
{
static T _new = new T(); //cached copy of structure
public static T New { get { return _new; } }
}
class Program
{
static void Main(string[] args)
{
St1 x1 = Factory<St1>.New;
St1 x2 = Factory<St1>.New;
St1 x3 = Factory<St1>.New;
St2 y1 = Factory<St2>.New;
St2 y2 = Factory<St2>.New;
}
}
Solution #1. Using a common interface for all the structures and a dictionary collection
public interface IStr { }
public struct St1 : IStr
{
public static int ID = 1;
}
public struct St2 : IStr
{
public static int ID = 2;
}
public class StructFactory : System.Collections.ObjectModel.KeyedCollection<int, IStr>
{
public static StructFactory Default = new StructFactory();
protected override int GetKeyForItem(IStr item)
{
FieldInfo finfo = item.GetType().GetField("ID",
BindingFlags.Static | BindingFlags.Public);
return (int)finfo.GetValue(item);
}
public StructFactory()
{
Add(new St1());
Add(new St2());
}
}
class Program
{
static void Main(string[] args)
{
St1 x = (St1)StructFactory.Default[1];
St2 y = (St2)StructFactory.Default[2];
}
}
The syntax you use above won't work since it means "create an array of AnotherStruct with five elements in it." As mentioned in a comment, however, you really should look into using a factory pattern.
However, if you really want to use the pattern above, you could change it up slightly. Have your AnotherStruct array hold Type instances of each of your structs. Then, your "creation" line would look more like:
structobject s = (structobject)Activator.CreateInstance(AnotherStruct[5]);
You can use reflection on the Assembly (since you are wrapping it in a DLL) to get those Type objects.
And finally, unless you have a really good reason for using struct (and understand all of the nuances, of which there are several), stick with class.

Categories

Resources