C# - understanding Objects, Classes, and Method interactions - c#

Very, very new programmer here facing some big troubles, I am trying to achieve as follows:
I want to write a very basic program in which the user is prompted to input two double variables, I then want the program to call separate methods, that will perform mathematical operations on those two variables and provide the user the answers.
Example of desired output:
Input First Number
x
Input Second Number
y
Add: z
Subtract: z
My aim in this is to practice using objects, but I am having issues, see this snippet as an example.
class Variables
{
public string First { get; set; }
public string Second { get; set; }
}
class Program
{
Variables inputs = new Variables()
{
Console.WriteLine("Please input first number"),
First = Console.ReadLine(),
Console.WriteLine("Please input second number"),
Second = Console.ReadLine(),
};
static void Main(string[] args)
{
Addthem();
}
public string Addthem()
{
double answer = Convert.ToDouble(inputs.First) + Convert.ToDouble(inputs.Second);
return ("Added: " + answer);
}
}
When trying to call Addthem, I have no 'object reference',
in my object 'inputs', I cannot print to console to prompt user input?
And finally (most mind bogglingly to me), my Main method is not suitable as an entry point for the program, this is what I am MOST clueless on.
Am I even on the right track? As I said very novice so sorry for egregious errors or general ignorance, I am just trying to better understand what I am not seeing in the interactions between Classes, Objects, Methods.

You've got all the ingredients right, but they need to be rearranged to make a good cake. Main() is the entry point, so anything you want to do has to be inside Main() or be called by something inside Main().
A useful concept to know is the difference between a class and an object.
A class is just a specification which says you can have these properties and methods, but you need to create an instance of the class first.
An object is an "instance" of a class and you can call the class methods (functions) through that object. Eg inputs is an instance of the Variables class.
using System;
class Variables
{
public string First { get; set; }
public string Second { get; set; }
public string AddthemInClass()
{
double answer = Convert.ToDouble(First) + Convert.ToDouble(Second);
return ("Added: " + answer);
}
}
class Program
{
static void Main(string[] args)
{
// You had the code to initialise `inputs` outside of Main(),
// so it wouldn't get executed
// It needs to be inside Main()
// `inputs` is created as an instance of the `Variables` class
Variables inputs = new Variables();
Console.WriteLine("Please input first number");
inputs.First = Console.ReadLine();
Console.WriteLine("Please input second number");
inputs.Second = Console.ReadLine();
// You need to tell Addthem() what to work on, ie, pass in `inputs`
var result = Addthem(inputs);
Console.WriteLine( result );
// Or, you could call AddthemInClass through the `inputs` object
// because AddthemInClass is a method of Variables class
var result2 = inputs.AddthemInClass();
Console.WriteLine( result2 );
}
// This should be a static method. If you don't do this, you need to have it
// in a class and call it through an instance of that class
// You could put it inside Variables class - see AddThemInClass()
public static string Addthem(Variables inputs)
{
double answer = Convert.ToDouble(inputs.First) + Convert.ToDouble(inputs.Second);
return ("Added: " + answer);
}
}

Related

How to set variables in array (within a foreach loop) to be accessed in a different class?

Basically, I have an array of data, which I have split into pairs. In this case string firstTicker and string secondTicker. I would like to run a job in a seperate class that uses the instances of the 'firstTicker' and 'secondTicker'. Is there a way to declare these strings so that they may be accessed outside?
static void Main(string[] args)
{
string _myPairList = GlobalVar.GlobalString;
//For reference: _myPairList="Joe,Brown;Bill,Lowry;Sara,Moncton"
string[] pairListArray = _myPairList.Split(';');
foreach (string tickerPair in pairListArray)
{
string[] tickerPairDualArray = tickerPair.Split(',');
// Command: I'd like to run a job in a seperate class with the two seperated
// tickers as variables for each set. (i.e. 'Joe' and 'Brown',
// 'Bill' and 'Lowry', 'Sara' and 'Moncton' are all run in the
// same program with the respective variables
string firstTicker = tickerPairDualArray[0];
string secondTicker = tickerPairDualArray[1];
}
Console.ReadLine();
}
Yes - in your other class that you've written, have your constructor or methods take string parameters. When you want to process those strings in your Main method, simply call YourMethod(firstTicker, secondTicker);, or if you want to add them to a class's data, MyClass obj = new MyClass(firstTicker, secondTicker);.
If you're simply wanting to call into another class which has the functionality you want, then Jeremy's answer should be good.
If you're wanting to be able to attach arbitrary code from another class to the loop, then an event is an effective way to go. Add something like the following to your code:
public static event EventHandler<TickerEventArgs> TickerLoopIterated;
private static void InvokeTickerLoopEvent(string firstTicker, string secondTicker)
{
if (null != TickerLoopIterated)
{
var args = new TickerEventArgs() { FirstTicker = firstTicker, SecondTicker = secondTicker };
TickerLoopIterated(this, args);
}
}
public class TickerEventArgs : EventArgs
{
public string FirstTicker { get; set; }
public string SecondTicker { get; set; }
}
And invoke it inside your loop when your values are ready
InvokeTickerLoopEvent(firstTicker, secondTicker);
Then in your other class, subscribe to the event somewhere in the code, probably in the initialization phase, like so:
NameOfTheClassWithYourTickerLoop.TickerLoopIterated += SomeCodeIWantToExecute;
And elsewhere in that class:
private void SomeCodeIWantToExecute(object sender, TickerEventArgs args)
{
//Your code here
}
Note that the event is static because your example is in the public static void main method. Throw that bad boy into an object class and you can use an instance event.

Using functions in c#

I am struggling to understand how functions work outside of main. I simply need to compute a total using information that is put in by the user in main, but I am supposed to call on a function to total this up. Here is the code I have so far, I am sure it is not very close to right, a nudge in the right direction would be a huge help
namespace ConsoleApplication17
{
class Program
{
static void Main(string[] args)
{
string customerName, customerState;
double numberItems, itemPrice;
Console.WriteLine("Please enter the customer name");
customerName = Console.ReadLine();
Console.WriteLine("Please enter the state in which you reside:");
customerState = Console.ReadLine();
Console.WriteLine("How many items were purchased?");
numberItems = int.Parse(Console.ReadLine());
Console.WriteLine("What was the price of said items?");
itemPrice = Convert.ToDouble(Console.ReadLine());
}
public static double ComputeTotal (double total)
{
double totalAmount;
Console.Write(total);
}
}
public static double ComputeTax (double totalAmount, string state, string fl, string nj, string ny)
{
if (state == fl)
return totalAmount*.06;
else if (state == nj)
return totalAmount*.07;
else if (state == ny)
return totalAmount*.04;
}
In short, I need to use the function ComputeTotal to multiply the numberItems and itemPrice
A function basically takes some data from you and returns (some other?) data to you.
In your case you want to give the function 2 pieces of data - qty and price, and you want it to return you the total price.
public static double ComputeTotal(double qty, double price)
{
return qty* price;
}
This function ComputeTotal accepts 2 variables of type double.
They are qty and price.
The function then multiplies these 2 variables and returns the result to the caller.
In your main method, this is how you use(call) the function.
static void Main(string[] args)
{
// rest of your code here
var total = ComputeTotal(numberItems, itemPrice);
Console.WriteLine(total);
}
Here I am creating a new variable called total, and I am assigning the return value of ComputeTotal function to this variable.
The ComputeTotal function requires 2 parameters and I am passing 2 variables that you created in your code. For brevity I have not typed any of your original code, and your code should be at the location of my comment "// rest of your code here" .
your method/function could be like this
public static double ComputeTotal (double itemPrice, int quantity)
{
return itemPrice * quantity
}
in your main method you can do like this
static void Main(string[] args)
{
double total_price=0.0;
total_price = ComputeTotal ( itemPrice, numberItems)
Console.WriteLine("totl price : {0}",total_price);
}
understand how functions work
I am distilling this significantly, but a function for this definition is really a method which returns a value. In C# there is no distinction between functions and methods for they are the same with differences being whether something returns data or operates on a referenced instance of a class instance.
The real difference is in the calling mechanism on whether one instantiates (calls new on a class); they are instantiatitng a class. For this assignment, your teacher does not want you to instantiate a class.
Hence you will call function(s) which are static methods that can be called by anyone without instantiating any classes.
With that in mind, your teacher wants you to learn a function type call so he /she wants you to create a static method off of the class Program which can be called by Main because it is static as well.
So create your function type static method that will return a value; hence it will mimic functions in other languages.
outside of main.
Now Main can have static methods, but so can other classes which can be called from within a Main's static method as well.
The other class like that looks like this...and is called by fully qualifying the location such as {ClassName}.{Static Method Name}.
class Program {
static void Main(...)
{
Console.WriteLine( TheOtherClass.AFunction() );
}
}
public class TheOtherClass
{
public static string AFunction()
{
return "A String From this Function. :-) ";
}
}
Note if TheOtherClass is in a different namespace, access it such as {Namespace}.{ClassName}.{Static Method Name}. But you should make sure that the other class is in the same Namespace as found in your current example of ConsoleApplication17.

Why do c# objects once behave like passed by value and once as passed by reference?

I don't understand one thing about passing parameters to methods in c#. From what I see objects in c# sometimes behave like the have been passed by reference and once as if they were passed by value. In this code I pass to method() one by reference and once by value. Both of these execute as expected. But when I created Update() and pass an object by value I see it behaving like it is updating original object.
Why do I update original object with Update(myString input) but do not update it with method(myString input)?
This is illogical!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassPassing
{
class Program
{
static void Main(string[] args)
{
myString zmienna = new myString();
Update(zmienna);
Console.WriteLine(zmienna.stringValue);
Console.WriteLine(zmienna.stringValue2);
Console.ReadLine();
zmienna.stringValue = "This has run in main";
zmienna.stringValue2 = "This is a help string";
method(zmienna);
Console.WriteLine(zmienna.stringValue);
Console.WriteLine(zmienna.stringValue2);
Console.ReadLine();
method(ref zmienna);
Console.WriteLine(zmienna.stringValue);
Console.WriteLine(zmienna.stringValue2);
Console.ReadLine();
}
static void method(myString input)
{
input = new myString();
}
static void method(ref myString input)
{
input = new myString();
}
static void Update(myString input)
{
input.stringValue2 = "This has run in update method";
}
}
public class myString
{
public string stringValue { get; set; }
public string stringValue2 { get; set; }
public myString() { stringValue = "This has been just constructed"; this.stringValue2 = "This has been just constructed"; }
}
}`
You have to understand your code:
static void method(myString input)
{
input = new myString();
}
Here you pass reference to object by value
static void method(ref myString input)
{
input = new myString();
}
Here you pass reference to object by reference
static void Update(myString input)
{
input.stringValue2 = "This has run in update method";
}
Here again you pass reference to object by value
Now:
When you pass object reference by value, you can change the contents of the object, but you cannot change the reference itself (assign it to another object).
When you pass object reference by reference, you can both change the contents of the object and you can modify the reference itself (assign it to another object).
The real passing by value in C# occurs only in case of simple (int, float, etc.) types and in case of structs:
class Program
{
public struct MyStruct
{
public int i;
}
public class MyClass
{
public int i;
}
public static void Modify(MyStruct s)
{
s.i = 99;
}
public static void Modify(MyClass c)
{
c.i = 99;
}
public static void Main(string[] args)
{
MyStruct myStruct = new MyStruct();
myStruct.i = 20;
MyClass myClass = new MyClass();
myClass.i = 20;
Modify(myStruct);
Modify(myClass);
Console.WriteLine("MyStruct.i = {0}", myStruct.i);
Console.WriteLine("MyClass.i = {0}", myClass.i);
Console.ReadKey();
}
}
Result:
MyStruct.i = 20
MyClass.i = 99
In this case, MyStruct's value remained unchanged, because it was passed to a function by value. On the other hand, MyClass's instance was passed by reference and that's why its value changed.
Objects aren't passed at all.
For expressions of a reference type (classes, interfaces etc) references are passed - by value by default, but the variables are passed by reference if you use ref.
It's important to understand that the value of zmienna isn't an object - it's a reference. Once you've got that sorted, the rest becomes simple. It's not just for parameter passing either - it's for everything. For example:
StringBuilder x = new StringBuilder();
StringBuilder y = x;
y.Append("Foo");
Console.WriteLine(x); // Prints Foo
Here the values of x and y are references to the same object - it's like having two pieces of paper, each of which has the same street address on. So if someone visits the house by reading the address written on x and paints the front door red, then someone else visits the same house by reading the address written on y, that second person will see a red front door too.
See my articles on reference and value types and parameter passing for more details.
There may be multiple questions to answer here, but regarding your last one:
"Why do I update original object with Update(myString input) but do not update it with method(myString input)?"
Here, you are creating a new instance of the myString class and not referencing the original that was passed to the method as a parameter. So if you change the value of input.stringValue2 inside the method, you will lose the value once you leave the method.
static void method(myString input)
{
input = new myString();
}
But here you are referencing the original instance passed to it. When you leave this method, the original myString instance will retain the value of stringValue2.
static void Update(myString input)
{
input.stringValue2 = "This has run in update method";
}
Imagine computer memory as a set of boxes, and that you can give them names using labels.
myString zmienna = new myString();
Here you allocate a box with an instance of myString in it, and have a label zmienna pointing to it. Then:
static void method(myString input)
{
input = new myString();
}
In this method, input is an another label. Calling the method you first make the label input point to the same box, with the initial instance. However in the method's body you allocate another box, and change the label input to point to that new box. Nothing is being done with the first box, and nothing is being done with zmienna label.
static void method(ref myString input)
{
input = new myString();
}
Here, because of the ref keyword you're not only passing the whereabouts of the first "memory box", but you give the actual label. So this method's body updates your label zmienna to point to a newly created box, with a second instance of myString. The first box is being forgotten, as no labels point to it.
static void Update(myString input)
{
input.stringValue2 = "This has run in update method";
}
In this case, you pass the address of the first box, in exactly the same manner as in the first method. So you have two labes: zmienna and input - both pointing to the same box. Therefore input.stringValue2 accesses the field stringValue2 in the same box that is pointed by zmienna.
A precise term actually used is reference instead of label term I'm using in this explanation. I somehow find that many people find it easier to comprehend this way :)

C# - How to access a static class variable given only the class type?

This is my first time posting on Stack Overflow, so hopefully I did everything right and you guys can help.
I'm wondering if in C# there's a way to access a static variable belonging to a class, when given only the type of the class. For example:
public class Foo
{
public static int bar = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
int tempInt = ??? // Get the value of the variable "bar" from "Foo"
Debug.WriteLine("Bar is currently :" + tempInt);
}
}
// I didn't run this code through a compiler, but its simple enough
// that hopefully you should get the idea...
It's hard to describe the context of needing to know this, but I'm making a game in XNA and I'm trying to use reference counting to reduce the complexity of the design. I have objects in the game and power-ups that can apply an effect them (that stays on the objects). Power-ups can die but their effects can still linger on the objects, and I need to keep track of if any effects from a power-up are still lingering on objects (thus, reference counting). I plan to make a "PowerUpEffect" class (for each type of power-up) with a static integer saving the number of objects still affected by it, but the design of the rest of the game doesn't work well with passing the PowerUpEffect all the way down to the object for it to call a method of the PowerUpEffect class.
I'm hoping to pass only the PowerUpEffect's type (using something like "typeOf()") and use that type to reference static variables belonging to those types, but I have no idea how to do it or if it's even possible.
I'd be glad to even find work-arounds that don't answer this questions directly but solve the problem in a simple and elegant design. =)
Help! (and thanks!)
If you only have the Type handle, you can do this:
var prop = givenType.GetProperty("bar");
var value = prop.GetValue(null);
I would use a Dictionary instead, which are probably the most concise way of mapping one set of values to another. If you are associating int values with Types, then do something like:
public static readonly Dictionary<Type, int> sTypeValues =
new Dictionary<Type, int>
{
{ typeof(Type1), 5 },
{ typeof(Type2), 10 },
{ typeof(Type3), 2 },
{ typeof(Type4), 3 },
{ typeof(Type5), -7 }
};
your function then becomes:
public void myFunc(Type givenType)
{
int tempInt = sTypeValues[givenType];
Debug.WriteLine("Bar is currently :" + tempInt);
}
int tempInt = (int) givenType.GetField("bar").GetValue(null);
Okay, so you have a collection of powerups, and you want to have an integer associated with each of those powerups. Rather than having a lot of classes, each with a static integer, you can have a single static collection which holds onto all of the powerups and their associated integer values.
public static class MyPowerupInfo
{
public static Dictionary<PowerUp, int> PowerUps {get; private set;}
static MyPowerupInfo
{
PowerUps = new Dictionary<PowerUp, int>();
PowerUps.Add(*some power up object goes here*, 0);
//TODO add other power ups
}
}
Then to use it you can do something like:
int powerupCount = MyPowerupInfo.PowerUps[wickedAwesomePowerup];
or:
public static void IncrementPowerup(Powerup powerup)
{
MyPowerupInfo.PowerUps[powerup] = MyPowerupInfo.PowerUps[powerup]+1;
}
If am getting you correc, this might give you some idea:
using System;
using System.Reflection;
public class RStatic
{
private static int SomeNumber {get; set;}
public static object SomeReference {get; set;}
static RStatic()
{
SomeReference = new object();
Console.WriteLine(SomeReference.GetHashCode());
}
}
public class Program
{
public static void Main()
{
var rs = new RStatic();
var pi = rs.GetType().GetProperty("SomeReference", BindingFlags.Static | BindingFlags.Public); // i have used GetProperty in my case
Console.WriteLine(pi.GetValue(rs, null).GetHashCode());
}
}
Are you assuming if the name of the field you're trying to access (for example, for the class "foo", the field "bar") is a different field based on the Type parameter?
If the name of the field is known based on a finite number of allowable types, you should be able to determine it with a switch statement. For example:
public class Foo
{
public static int bar = 0;
}
public class Baz
{
public static int bing = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
switch (givenType.ToString())
{
case "Foo":
Debug.WriteLine("Bar is currently :" + Foo.bar);
break;
case "Baz":
Debug.WriteLine("Bing is currently :" + Baz.bing);
break;
}
}
}

Need Help With a Simple C# Program!

I Want to call a class into the Main method.. And I'm getting this error :s
Code:
using System;
namespace AddMinusDivideMultiply
{
class Program
{
public static int i, j;
public static void Main()
{
Console.Write("Please Enter The First Number :");
string temp = Console.ReadLine();
i = Int32.Parse(temp);
Console.Write("Please Enter The Second Number :");
temp = Console.ReadLine();
j = Int32.Parse(temp);
Minuz.minus(); // Here its generating an Error - Error 1 The name 'Minuz' does not exist in the current context
}
}
class Terms
{
public static void Add()
{
int add;
add = Program.i + Program.j;
Console.WriteLine("The Addition Of The First and The Second Number is {0}", add);
}
class Minuz
{
public static void Minus()
{
int minus;
minus = Program.i - Program.j;
Console.WriteLine("The Subraction Of The First and The Second Number is {0}", minus);
}
}
}
}
Case matters in C#!
Call this:
Minuz.Minus();
Also, need to change your braces so it's not inside Terms:
class Terms
{
public static void Add()
{
int add;
add = Program.i + Program.j;
Console.WriteLine("The Addition Of The First and The Second Number is {0}", add);
}
}
class Minuz
{
public static void Minus()
{
int minus;
minus = Program.i - Program.j;
Console.WriteLine("The Subraction Of The First and The Second Number is {0}", minus);
}
}
That's because the Class Minuz is defined inside the Class Terms so it really is not defined in the context you are trying to use it.
You did not close the definition of Terms before declaring Minuz
The problem is that the class Minuz is declared inside the class Terms, and it is private. This means that it is not visible from the Main method.
There are two possible ways to solve it:
Make the class Minuz internal or public and chance the call to the Minus method to Terms.Minuz.Minus()
Move the declaration of the class Minuz out from the Terms class so that it is instead declared in the namespace.
Also, as pointed out by others; mind the case of the method name. That will be your next problem once the class visibility has been fixed.
You have embedded the Minuz class inside the Terms class. If you make it public class Minuz you can call
Terms.Minuz.Minus();
to solve the error. But you probably want to move the Minuz class out of Terms.
Unless its a typo, you're missing a closing bracket for the Terms class. The way its currently written in your post, you would need to put this statement in your Main method:
Terms.Minuz.Minus();

Categories

Resources