Creating class instances at run-time and initializing simultaneously - c#

I am attempting following code to create multiple instances of a class at run-time and want to initialize also, but it is giving error:
A local variable named 'inum' cannot be declared in this scope because
it would give a different meaning to 'inum', which is already used in
a 'parent or current' scope to denote something else.
public class MyClass
{
static int i=0;
class A
{
public A()
{
}
}
public static void Run()
{
string inum = "i";
for (int j=1;j<=5;j++)
{
inum = inum + j.ToString();
//Initialize Instance
A inum = new A();
}
}
}

You appear to be trying to use variable names "dynamically". That doesn't work in C#, and you should change how you think about variables. If you want to create several instances, declare an array:
public class MyClass
{
static A[] instances;
class A
{
public A()
{
}
}
public static void Run()
{
instances = new A[5];
for (int j=0;j<5;j++)
{
instances[j] = new A();
}
}
}

You cannot have dynamic variable in c#. The append you are trying is appending the value not the variable pointer.
rather use this way
Dictionary<int, A> inum = new Dictionary<int, A>();
for (int j=1;j<=5;j++)
{
//Initialize Instance and add to dictionary
inum.Add(j, new A());
}
You can get them by key name. There are several other way to store instances as collection

I'm not a C# programmer by any stretch of the imagination, but by the rules of Java and any other similarly syntaxed language I know anything about, what you are doing is attempting to redeclare 'inum' with a new type, after it has been declared as a string in the same scope.
The other point is that even if this were not the case, you are not creating multiple instances but filling the same variable with a new instance 5 times, which would only result in one instance (the last one).
From quickly reading a C# tutorial I think this is something like what you want. I'm not sure what you were trying to do with the 'inum' variable so it is gone, as is static variable 'i':
public class MyClass
{
class A
{
public A()
{
}
}
public static void Run()
{
// Declare array to hold instances
A[] instances;
// instances is now five elements long
instances = new A[5];
for (int j=0;j<5;j++)
{
//Initialize Instance
instances[j] = new A();
}
}
}
That should result in an array of 5 objects called 'instances' in the scope of the Run method - you may want this in the scope of the class itself, possibly as a static property.
As a side note, it's good practice to start at 0, not 1, for operations like this (with the var 'j') and the above code reflects this.

you cannot call the variable of type A "inum" (there exists already one called like that)
you have to give it another name like:
A anyOtherName = new A();

try to name the variable A with different name
A objA = new A();

Related

Why can't my declared non static field be accessed inside static method?

Hi I am new to C# and I am aware on a surface level that I cannot use non static fields inside static methods. But I have a situation that I am trying to understand conceptually.
Check out this code snippet:
class CIMConversionHelper
{
private static Logger Logger = LogManager.GetCurrentClassLogger();
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
public static TDX2KlarfResult HandleConversion(TDXProcessItem item, string fileName)
{
TDX2KlarfResult result = new TDX2KlarfResult();
result.success = true;
XmlDocument doc = new XmlDocument();
try
{
doc.Load(fileName);
}
catch (Exception ex)
{
result.success = false;
Logger.Error(ex, "XML Parsing Error: ");
return result;
}
_procEndTimeData.ToolType = toolType;
_procEndTimeData.Lot = input.cimToolContext.LOT;
_procEndTimeData.WaferScribe = input.cimWaferContainer.waferContext.WAFER_SCRIBE;
_procEndTimeData.Processing_End_Time = input.cimToolContext.PROCESSING_END_TIME;
}
public static TDX2KlarfResult Convert(TDXProcessItem item, string fileName)
{
TDX2KlarfResult result = new TDX2KlarfResult();
result.success = true;
try
{
result = CIMConversionHelper.HandleConversion(item, fileName);
}
catch (Exception ex)
{
// Failed to Parse the xml Not good mark nonrecoverable error and return.
result.errorType = "Non-Recoverable";
result.success = false;
Logger.Error(ex, "Unknown Error: ");
return result;
}
if (result.success)
{
//DBHelper.AddProcessingEndTimeToDB();
}
return result;
}
}
This is a very abridged snippet but one that captures my question. I have created an object reference as field for ProcessingEndTimeData called _procEndTimeData.
Why then is it telling me in Visual Studio that:
"an object reference is required for the non-static field, method, or property CIMConversionHelper._procEndTimeData?
I thought I should be able to assign values to the declared object "_procEndTimeData" in the 4th line inside the static function "HandleConversion"
Can someone explain to me why this reference is not enough? and why I would then have to create yet another ProcessingEndTimeData object inside the static function HandleCOnversion?
I know I can just toggle _procEndTimeData to be static but why do I need to do this if I have already created a reference in the field level?
Think about the memory of the equipment.
When you create an object, memory is reserved for it. Imagine, that because of its properties (int, char...) it occupies 32 bytes. If you create 10 objects, you will have 320 bytes occupied in memory for your objects.
But when you use "static", those properties are created only once for the class. Not once for each object you create.
So, your 10 objects can access their own properties (int, char...) and also the static ones. But from a "static" method you cannot access the properties of an object of that class because you don't have the instance of it.
A very simple example: You have a User class with the Name property. You add a static variable of type integer: static int count. That variable will be used to record the number of users you create.
In the constructor of the user you can do count++ because the instances of the class can access to the properties of the class. But if you create a static method:
public static void DoSomething()
{
// You can show a message with the number of users
MessageBox.Show(count.ToString());
// But you CAN'T access to a "Name" because this method is not
// a method of one concrete user. It's a general method, for all users
}
If you invoke DoSomething and you are created two users, "Tom" and "Jerry", in DoSomething you don't know any user.
You have 2 choices to make this work. Not sure which one applies. My guess is the first one I will show
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
change to
static private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
This says that this field is also static, ie belongs to the class, not to instances of the CIMConversionHelper class.
The alternative, which I dont think you want it to create an instance of CIMConversionHelper in that method. Which as I said is probably not what you want.
If your intent is that this class (CIMConversionHelper) is all static, ie you will never create an instance of it then mark the class itself static and the compiler will ensure that you dont accidentally create non static members. ie
static class CIMConversionHelper{....}
Why is this so?
You say you have created a reference here
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
YOu have not created it yet.
You need to understand the difference between static and instance functions and fields.
Lets have an example. We have a class Thingy. It includes a factory method that makes thingy instances and keeps a count of how many it has made
public class Thingy{
static s_thingyCount = 0;
string _froop;
public static CreateThingy(){
var thing = new Thingy();
......
s_thingyCount++;
thing._froop = "hello";
return thing;
}
public void Twang(int froop){
......
}
public int Oink(string pling){
......
_froop = pling;
}
}
we can go
var t1 = Thingy.CreateThingy();
t1.Oink("Ole");
The CreateThingy does not operate on instances of the class, it operates on the class itself. The count variable does not belong to an instance, it belongs to the class itself. Note that in the create method we have to say
thing._froop = "hello";
ie which objects _froop we want to set (the one we are in the process of making).
var t1 = Thingy.CreateThingy();
now we have an instance of Thingy we can call methods on it
t1.Oink("Ole");
Look in that method
public int Oink(string pling){
......
_froop = pling;
}
we dont say which froop to set, we are manipulating an instance of the class.
We cannot do
Thingy.Oink("xxx");
Which THingy would be updates? Nor can we do
Thingy._froop = "fff";
for the same reason
but we can do
var count = Thingy.s_thingyCount;
How does this map to your class. THis method is static. It is like CreateThingy, it does not have an instance to operate on.
public static TDX2KlarfResult HandleConversion(TDXProcessItem item, string fileName)
but you do this
_procEndTimeData.ToolType = toolType;
with this field
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
this is just like doing
_froop = "hello"
in CreateThingy
_proceEndTimeData only exists in instances on your class.
It will be create when you do
new CIMConversionHelper();
But I suspect thats not what youo want to do. So you need to make _proceEndTimeData static, just like s_thingyCount
If I'm understanding it correctly, you answered yourself: "I am aware on a surface level that I cannot use non static fields inside static methods", and then you have declared a non static variable inside your method:
private readonly ProcessingEndTimeData _procEndTimeData
It should be static, apart than readonly if you want.
The reason for this has to do with object oriented programming. To access a static method from a class you don't need to instantiate it. This is why you can't reference class-level non static variables inside a static method from that class. Hope that made it a little clearer.
I know I can just toggle _procEndTimeData to be static but why do I need to do this if I have already created a reference in the field level?
You created no such thing, your _procEndTimeData is a field in every instance of CIMConversionHelper, of which you have none.
If it helps you visualize the problem better, imagine what would happen if your expectation was reality and you had the following code:
CIMConversionHelper h1 = new(), h2 = new();
CIMConversionHelper.Convert(.....whatever....);
Would it change h1._procEndTimeData? h2._procEndTimeData? It has to pick one, right? So which one does it pick?
No. static methods can only use static fields, period.

c# doesn't work struct adding to list

I have
struct Park
{
...
}
and I need, to add 10 elements of this struct to List.
public List<Park> Parks = new List<Park>();
static void Main(string[] args)
{
new Program().CreatePark();
...
}
public void CreatePark()
{
for (int i = 1; i <= 10; i++)
{
Park temp = new Park();
temp.ID = i;
temp.Number = "abc";
temp.Property = false;
try
{
Parks.Add(temp);
}
catch (ArgumentException)
{
Console.WriteLine("oh no :(");
}
Console.WriteLine(temp.ToString());
}
}
And this doesn't work. Console.WriteLine(temp.ToString()); - this shows struct element, but when I want to print all elements, from Parks it's not working.
Parks.Count shows 0.
Given that you're using the statement: new Program().CreatePark(); the list of objects that you've created is not accessible after you create them. You have already thrown away the instance of the object holding the List. You have no way to access the list that you created to know what you had put in it.
The only thing the rest of your code could possibly do is create an entirely separate instance that has its own list, one that is entirely different from the one that you populated.
You'll need to hold onto the reference to the Program object if you want to inspect the list after you've populated it.
Parks is an instance variable.
CreateParks is an instance method.
Main is a static method, so you can't access the instance method or variable from it.
new Program() creates a new instance of the Program class.
Since the newly created program is not stored in a variable, it is discarded, and you can't access its Parks list after that.
To access the Parks list, you need to keep a reference to the instance of the program class like this:
Program program = new Program();
program .CreateParks();
foreach(Park park in program .Parks)
{
// Do something with the park
}
For anything more than a simple program, you will be better off having all the logic which isn't related to starting the program outside the Program class.
For example, you could create a new ParkManager class which is responsible for creating the parks and providing access to them.
Your program would look a bit like this:
public static class Program
{
static void main(string[] args)
{
ParkManager parkManager = new ParkManager();
parkManager.CreateParks();
foreach (Park park in parkManager.Parks)
{
// do something with park
}
}
}
public class ParkManager
{
// Setter is private to prevent other classes from replacing the list
// This doesn't prevent other classes from adding or removing,
// replacing or editing items in the list
public List<Park> Parks {get; private set;}
// Constructor - you could populate the list from here if appropriate
public void ParkManager()
{
Parks = new List<Park>();
}
public void CreateParks()
{
// Populate the list of parks here
}
}

Type confusion: A type is class, a variable and an object?

I'm currently working through the Pluralsight C# 5.0 course, and I'm relatively new to programming.
I previously thought I understood the concept of Data Types on a basic level, Int/Array/Strings etc.
In this course it starts to introduce C#'s huge emphasis on Types, and creating your own custom types.
One of the course code snippets which I've included below, is refusing to sink in and I was hoping
someone could provide some clarity or a different way of thinking about it.
Program.cs:
GradeStatistics stats = book.ComputeStatistics();
GradeStatistics.cs:
namespace Grades
{
public class GradeStatistics
{
public GradeStatistics()
{
HighestGrade = 0;
LowestGrade = float.MaxValue;
}
public float AverageGrade;
public float HighestGrade;
public float LowestGrade;
}
}
Grades:
public GradeStatistics ComputeStatistics()
{
GradeStatistics stats = new GradeStatistics();
float sum = 0f;
foreach (float grade in grades)
{
stats.HighestGrade = Math.Max(grade, stats.HighestGrade);
stats.LowestGrade = Math.Min(grade, stats.LowestGrade);
sum += grade;
}
stats.AverageGrade = sum / grades.Count;
return stats;
}
I'm finding it particularly difficult to understand what exactly GradeStatistics is.
In the course it is referred to as not only a class, but as a variable, and furthermore also
being returned as an object in Grades.
Any clarity is appreciated, as I'm finding it a little difficult to follow with all of the
above terms being thrown around.
GradeStatistics is a class, from this declaration:
public class GradeStatistics
stats is a variable of type GradeStatistics, from this declaration:
GradeStatistics stats = new GradeStatistics();
The return type of ComputeStatistics is GradeStatistics, from this declaration:
public GradeStatistics ComputeStatistics()
So, it's a class. It is being used to declare a variable with a particular type, and it is used to declare what a particular method will return, an object of the type.
If it helps, you can sort of think of a type as a blueprint. You can have a blueprint of a house. This will tell you that "if you had a house", this is what it would look like.
When you construct an instance of the type, ie. build the house, you get an instance. It has a type (it follows the blueprint), but it may be different from other instances, having other property values (like the color of the paint used, or the style of doors).
First, GradeStatistics is a Class.
Second, it is not referred as a variable anywhere. But stats is actually a variable of type GradeStatistics in this line.
GradeStatistics stats = new GradeStatistics();
Third, ComputeStatistics is a function which return GradeStatistics.
And if you have read OOP than you should know that any object of any class type can be returned as a function return value.
GradeStatics is a class by definition. When you use the new keyword you are creating an instance of that class (an object) which you can pass around or assign it to a variable.
So your snippets above, GradeStatistics is defined as a class in the gradestatics.cs file. Grades.cs creates an instance of this class in the computestatics method and assigns it to the stats variable which is populated in yhat method and then returned
GradeStatistics is a class. From this snippet:
public class GradeStatistics
{
public GradeStatistics()
{
HighestGrade = 0;
LowestGrade = float.MaxValue;
}
public float AverageGrade;
public float HighestGrade;
public float LowestGrade;
}
However, in the method ComputeStatistics, the return type is GradeStatistics, not void as you are probably accustomed to. This means that ComputeStatistics returns a GradeStatistics. Lets look at an easier example.
Suppose we have a class Foo. It is constructed like:
public class Foo
{
public int a;
public int b;
public Foo()
{
a = 0;
b = 0;
}
}
Now we can create Foos and access them normally.
Foo foo = new Foo();
foo.a = 4;
foo.b /= 2;
Now suppose we want to do this, except many times, so we create a method.
public Foo IncrementFoo(int amount, int divideBy)
{
Foo obj = new Foo();
obj.a = amount;
obj.b /= divideBy;
return obj;
}
This method creates a new object of type Foo, and returns it. You can then use this code like:
Foo newFoo = IncrementFoo(4, 2);
//foo == newFoo
I would recommend you read more here, especially about return types.
Note: In this case, it may be better to write an Extension method, especially if we want to modify a single instance of a Foo, but we don't want to get into that. Also if we were really wanting to create a new instance of Foo like that, it would be better to use a constructor.

C# array is a field but is used like a type [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
(object) is a 'field' but is used like a 'type'
As you might have guessed from the title am I getting this error:
Invasion_server.variables.resources is a field but is used like a type
The code that is giving me that error is:
class variables
{
....
public static string[] resources = new string[30];
resources[0] = "cities_wood";
....
}
Could someone please tell me what is causing the problem, because elsewhere in the code it is working...
You should do this in some method
If you would like to initialize the members of the array outside of a constructor or method body, you would need to do so using the initializer syntax with the declaration:
class variables
{
public static string[] resources = new string[30]
{
"item one",
"item two",
...
}
}
The downside to doing so is that you'd be required to populate all 30 values. If you're looking to just populate the first, then you'll need to do so either in a constructor or method body. You could consider a static constructor, which would have the same net effect as initializing when declared; the static constructor is run the first time a member of the class is accessed. For example:
class variables
{
public static string[] resources;
static variables()
{
resources = new string[30];
resources[0] = "item one";
}
}
Try this:
class variables
{
public static string[] resources = new string[30];
static void doSomething() {
resources[0] = "cities_wood";
}
}
you were not assigning the variable within a class constructor or a method.
It's because you're trying to do operations on a variable in the class body, rather than in a method. You should only have a few things in your class body:
Fields: int myField = 0;
Methods: public void myMethod(){ }
Constructors/Destructors (just a special type of method): public MyClass(){}
So when the compiler sees anything that is the first word following a ; (meaning that it is the first word of a new line of code), it expects to see either an identifier like public, static, etc, or a Type, like int. Since it wasn't an identifier, it looked for a type, and since it wasn't a type, you got your error.
Hope that explains it pretty well.
you cannot do
resources[0] = "cities_wood";
in your class definition. Do it in a static constuctor or using a list initializer.
You have to initialize the fields in a method or constructor or all in the declaration like
class variables
{
public static string[] resources = new string[30];
public variables()
{
resources[0] = "cities_wood";
}
}
OR
public static string[] resources = {"cities_wood", "....", "more stuff", "and more stuff"};//Your 30 or les or more variables separated by a comma

access base class variable in derived class

class Program
{
static void Main(string[] args)
{
baseClass obj = new baseClass();
obj.intF = 5;
obj.intS = 4;
child obj1 = new child();
Console.WriteLine(Convert.ToString(obj.addNo()));
Console.WriteLine(Convert.ToString(obj1.add()));
Console.ReadLine();
}
}
public class baseClass
{
public int intF = 0, intS = 0;
public int addNo()
{
int intReturn = 0;
intReturn = intF + intS;
return intReturn;
}
}
class child : baseClass
{
public int add()
{
int intReturn = 0;
intReturn = base.intF * base.intS;
return intReturn;
}
}
I want to access intF and intS in child class whatever i input.. but i always get the values of both variables 0. 0 is default value of both variables.
Can anyone tell me that how can i get the value???
thx in adv..
Yes, Zero is what you should get, since you made single instance of child class and did not assign any value to its inherited variables,
child obj1 = new child();
rather you have instantiated another instance of base class separately and assign value to its members,
baseClass obj = new baseClass();
both runtime both the base class instance and child instance are totally different objects, so you should assign the child values separately like
obj1.intF = 5;
obj1.intS = 4;
then only you shall get the desired result.
You've got two separate objects - that's the problem. The values of the base class variables in the object referred to by obj1 are 0, because they haven't been set to anything else. There's nothing to tie that object to the object referred to by obj.
If you need to access the variables of another object, you'd have to make that object available to the one trying to access the data. You could pass obj as an argument to a method, or perhaps make it a property. There are lots of different approaches here, but we don't know what the bigger picture is - what you're really trying to do. Once you understand why it's not working as you expect it to, you can start thinking about what you're really trying to do.
Just to be clear, this has nothing to do with inheritance. It has everything to do with you creating two distinct objects. You'd get the same effect if you just used a single class, but created two different instances of that class.

Categories