Access object of a class from other classes - c#

I realise this is probably a very simple question and will be answered in no time. But wondering what to do. I have a class called Budget with an object named 'user01' I would basically like to be able to access that object across multiple classes, similar to the code below.
Main
static void Main(string[] args)
{
Budget user01 = new Budget(1000);
}
Budget Class
class Budget
{
private int _budget;
public Budget(int budget)
{
_budget = budget;
}
public int UserBudget
{
get { return _budget; }
set { _budget = value; }
}
}
Expense Class
class Expenses
{
// What I've been trying to do...
public int Something(user01.budget)
{
user01.budget - 100;
return user01.budget;
}
}
I'm not really sure where to go from here, and am hoping to a little help/explanation. Many thanks

This is invalid:
public int Something(user01.budget)
But you can supply an instance of a Budget object to that method:
public int Something(Budget budget)
{
budget.UserBudget -= 100;
return budget.UserBudget;
}
Then you can invoke that method from your consuming code:
Budget user01 = new Budget(1000);
Expenses myExpenses = new Expenses();
int updatedBudget = myExpenses.Something(user01);
The method doesn't "access the variable user01". However, when you call the method, you supply it with your user01 instance. Inside of the method, the supplied instance in this case is referenced by the local budget variable. Any time you call the method and give it any instance of a Budget, for that one time that instance will be referenced by that local variable.
Go ahead and step through this using your debugger and you should get a much clearer picture of what's going on when you call a method.
(Note that your naming here is a bit unintuitive, which is probably adding to the confusion. Is your object a "budget" or is it a "user"? Clearly defining and naming your types and variables goes a long way to making code easier to write.)

Its a pretty simple change to your Expenses class:
class Expenses
{
// What I've been trying to do...
public int Something(Budget userBudget)
{
userBudget.UserBudget -= 100;
return userBudget.UserBudget;
}
}
Which you then call like this from your main class:
static void Main(string[] args)
{
Budget user01 = new Budget(1000);
Expenses expenses = new Expenses();
var result = expenses.Something(user01);
}
Or, if you make your Something method static you can call it without an instance:
class Expenses
{
// What I've been trying to do...
public static int Something(Budget userBudget)
{
userBudget.UserBudget -= 100;
return userBudget.UserBudget;
}
}
Which you call like this:
static void Main(string[] args)
{
Budget user01 = new Budget(1000);
var result = Expenses.Something(user01);
}
Its important when designing methods to remember that a method takes in a general argument and its the caller that passes in something specific.

Related

C# How to create your own data structure methods

I've been trying to google one interesting fact for me, but can't grab the terminology to fully understand this concept. For example, I create my own container which holds an array of Cars. For this specific array I want to implement "Place" method which inserts a given car in a specific order (place method has logic). And what I don't get is how it gets the job done. Here is the code:
public static void Main(string[] args)
{
Car[] result = new Car[entries];
result.Place(poppedValue);
}
public static class Extension
{
public static void Place(this Car[] array, Car car)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] != null)
{
if (array[i].Year > car.Year)
{
}
}
}
}
}
public class Car
{
public string Name;
public int Year;
public double MPG;
public Car(string name, int year, double mpg)
{
this.Name = name;
this.Year = year;
this.MPG = mpg;
}
public bool ComplexMaths()
{
return (Year * MPG) % 2 == 0;
}
}
What I don't get is that in "Place" method, first argument is "this Car[] array" and when calling the method "Place" you don't give that argument. C# understands it by using result.Place... It's so confusing. Maybe someone can say what happends under the hood and how this "function" of C# is called. I would like to read about it more. Thank you.
An extension method is a syntactic sugar that allows functionality to be added to existing classes even if sealed and without inheriting them.
This is also called a Trait.
In C# we use the keyword this for the first parameter to indicate that the static method, that must be in a static class generally called a Helper class, applies to the specified type.
For example:
public static class CarArrayHelper
{
public static void Place(this Car[] array, Car car)
{
}
}
Indicates that we can apply the Place method on all arrays of Car.
Hence we can write:
var myArray = new Car[10];
myArray.Place(new car());
This is exactly the same as:
CarArrayHelper.Place(myArray, new car());
The Car class does not implement Place, so we added the functionality without changing the Car class or creating a subclass.
Here are some tutorials:
C# - Extension Method (TutorialsTeacher)
Extension Methods in C# (C-SharpCorner)
Extension Method in C# (GeeksForGeeks).

c# virtual static members

Yeah, I know there aren't any virtual static members in c#, but I have a problem where they would be really helpful and I can't see a good way to proceed.
I've got a standard kind of system where I send packets of data over a communication channel and get back responses. The communication system needs to know how many bytes of response to wait for, and the length of the response is fixed for each command type, so I have this code defined:
public abstract class IPacket
{
public abstract int ReceiveLength { get; }
public abstract byte[] DataToSend();
}
public class Command1 : IPacket
{
public override int ReceiveLength { get { return 3; } }
public Command1() { }
}
public class Command2 : IPacket
{
public override int ReceiveLength { get { return DataObject.FixedLength; } }
public Command2(int x) { }
}
public class Command3 : IPacket
{
static DataHelperObject Helper;
public override int ReceiveLength { get { return Helper.DataLength(); } }
static Command3()
{
Helper = new DataHelperObject();
}
public Command3(really long list of parameters containing many objects that are a pain to set up) { }
}
Notice that in each case, ReceiveLength is a fixed value - sometimes it's a simple constant (3), sometimes it's a static member of some other class (DataObject.FixedLength) and sometimes it's the return value from a member function of a static member (Helper.DataLength()) but it's always a fixed value.
So that's all good, I can write code like this:
void Communicate(IPacket packet)
{
Send(packet.DataToSend());
WaitToReceive(packet.ReceiveLength);
}
and it works perfectly.
But now I would like to output a summary of the packets. I want a table that shows the command name (the class name) and the corresponding ReceiveLength. I want to be able to write this (pseudo)code:
foreach (Class cls in myApp)
{
if (cls.Implements(IPacket))
{
Debug.WriteLine("Class " + cls.Name + " receive length " + cls.ReceiveLength);
}
}
But of course ReceiveLength requires an object.
I don't think I can use attributes here, c# won't let me say:
[PacketParameters(ReceiveLength=Helper.DataLength())]
public class Command3 : IPacket
{
static DataHelperObject Helper;
static Command3()
{
Helper = new DataHelperObject();
}
public Command3(really long list of parameters containing many objects that are a pain to set up) { }
}
because custom attributes are created at compile time (right?), long before the static constructor gets called.
Constructing objects of each type isn't particularly pleasant (pseudocode again):
foreach (Class cls in myApp)
{
IPacket onePacket;
if (cls is Command1)
onePacket = new Command1();
else if (cls is Command2)
onePacket = new Command2(3);
else if (cls is Command3)
{
Generate a bunch of objects that are a pain to create
onePacket = new Command3(those objects);
}
Debug.WriteLine("Class " + cls.Name + " receive length " + onePacket.ReceiveLength);
}
I need ... a virtual static property.
One solution would be to throw all compile-time safety over board and simply use reflection to access your static property like so: http://fczaja.blogspot.ch/2008/07/accessing-static-properties-using-c.html
Alternatively, you could separate out that information into a "PaketSizeManager" type which would simply have either the above-mentioned Dictionary or some switch-case statement plus some neat way to access this information from the outside, as in a public int GetSize(Type t){ .../* use dictionary or switch-case here */... } method. That way you would have encapsulated the size aspect of all your entities into a separate class.
Just make a public static CommandX.Length property, have it return what your ReceiveLength property is now, then have ReceiveLength refer to it. To get the best of both worlds, first you need both worlds.

c# - Initialize List<> from another class

I have defined a class which has List<>. I have shortened my Code. It is too large. There are too many List<>& in Method1() there is lots of code. Here is my code :-
public class Time : ITime
{
public List<Table1> Setts1 = new List<Table1>();
public List<Tabl2> Setts2 = new List<Table2>();
public void LoadSettings1(int companyId)
{
Setts1 = ctx.tblSett1.Where(a => a.CompanyId == companyId).Select(a => a).ToList();
}
public double Method1()
{
var data = Setts1.Where(m => m.SetType == "TYPE1").Select(m => m.Value1).FirstOrDefault();
......
......
}
}
I want to use Method1() in another class. My issue is Setts1 which is preloaded in the Time Class. So when it is used in within the Time class it has Records. But when i call it from another class obviously Setts1 will have no records. I tried to initialize it from another class like this :-
public class Class
{
.....
Time cls = new Time();
cls.Setts1 = ....;
cls.Method1();
}
But Setts1 shows no records when in Method1. How to initialize the List<> from another class?
Exposing field members of a class, outside of the class is not a good practice. So I recommend using properties like this:
//Mark the field member as private
private List<Table1> _Setts1 = new List<Table1>();
//Use Property to access the field outside of the class
public List<Table1> Setts1
{
get
{
if (_Setts1==null || _Setts1.Count()==0) //or any other logic you need
{
//Initialize the field memeber
_Setts1 = ctx.tblSett1.Where(a => a.CompanyId == companyId).Select(a => a).ToList();
}
return _Setts1
}
}
This way you can forget about methods like LoadSettings1 and it doesn't matter whether you use the Setts property inside the class or outside, it will be initialized at the right time.
You have to call 'LoadSettings1(int companyId)'. This is the method which brings the records and populates your 'List'.
public class Class
{
.....
Time cls = new Time();
cls.LoadSettings1(1);
cls.Setts1 = ....;
cls.Method1();
}
public class Something
{
private Time cls = new Time();
public Something(int companyId)
{
cls.LoadSettings1(companyId);
}
public void CallMethod1()
{
cls.Method1();
}
}
Something like this? Using constructor for your "other class" to LoadSettings.
cls.Setts1 = ....;
Actually I don't see how your code would not work, even if as Hossein said, it's bad practice. Look into how you're setting cls.Setts1 (the .... part). That's most probably the culprit

What is the use of "this" in Java and/or C#? [duplicate]

This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 9 years ago.
Say I have a simple sample console program like below. My question is in regards to this. Is the sole use of this just so you can use the input variable name to assign to the instance variable? I was wondering what the use of this is other than used in the context of this program?
public class SimpleClass {
int numberOfStudents;
public SimpleClass(){
numberOfStudents = 0;
}
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
public void printStudents(){
System.out.println(numberOfStudents);
}
public static void main(String[] args) {
SimpleClass newRandom = new SimpleClass();
newRandom.setStudent(5);
newRandom.printStudents();
}
}
Previously, when I needed to assign a value to an instance variable name that shares similarities to the input value, I had to get creative with my naming scheme (or lack of). For example, the setStudent() method would look like this:
public void setStudent(int numberOfStudentsI){
numberOfStudents = numberOfStudentsI;
}
From that example above, it seems like using this replaces having to do that. Is that its intended use, or am I missing something?
Things are quite the opposite of how you perceive them at the moment: this is such an important and frequently used item in Java/C# that there are many special syntactical rules on where it is allowed to be assumed. These rules result in you actually seeing this written out quite rarely.
However, except for your example, there are many other cases where an explicit this cannot be avoided (Java):
referring to the enclosing instance from an inner class;
explicitly parameterizing a call to a generic method;
passing this as an argument to other methods;
returning this from a method (a regular occurrence with the Builder pattern);
assigning this to a variable;
... and more.
this is also used if you want to a reference to the object itself:
someMethod(this);
There is no alternative to this syntax (pun intended).
It's also used to call co-constructors, and for C# extension methods.
'this' simply refers to the object itself.
When the compilers looks for the value of 'numberOfStudents', it matches the 'closest' variable with this name. In this case the argument of the function.
But if you want to assign it to the class variable, you need to use the 'this.'-notation!
In the method
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
for example.
'this.numberOfStudents' references the class variable with the name 'numberOfStudents'
'numberOfStudents' references the argument of the method
So, this method simple assigns the value of the parameter to the class variable (with the same name).
in c# you use this to refer the current instance of the class object immagine you have class like this from msdn
class Employee
{
private string name;
private string alias;
private decimal salary = 3000.00m;
// Constructor:
public Employee(string name, string alias)
{
// Use this to qualify the fields, name and alias:
this.name = name;
this.alias = alias;
}
// Printing method:
public void printEmployee()
{
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
// Passing the object to the CalcTax method by using this:
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this));
}
public decimal Salary
{
get { return salary; }
}
}
class Tax
{
public static decimal CalcTax(Employee E)
{
return 0.08m * E.Salary;
}
}
class MainClass
{
static void Main()
{
// Create objects:
Employee E1 = new Employee("Mingda Pan", "mpan");
// Display results:
E1.printEmployee();
}
}
/*
Output:
Name: Mingda Pan
Alias: mpan
Taxes: $240.00
*/
You have different scopes of variables in Java/C#. Take this example below. Although this.numberOfStudents and numberOfStudents have the same name they are not identical.
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
this.numberOfStudents is a variable called numberOfStudents that is in the instance of this class. this always points on the current instance.
public void setStudent(int numberOfStudents) that numberOfStudents is a new variable that is just available in this method.
keyword "this" refers to an object of the current class (SimpleClass) on the fly.
public class SimpleClass(){
private int a;
private int b;
private int c;
public SimpleClass(int a, int b){
this.a = a;
this.b = b;
}
public SimpleClass(int a, int b, int c){
// this constrcutor
this(a,b);
this.c = c;
}
}

How can I create temporary objects to pass around without explicitly creating a class?

I frequently find myself having a need to create a class as a container for some data. It only gets used briefly yet I still have to create the class. Like this:
public class TempObject
{
public string LoggedInUsername { get; set; }
public CustomObject SomeCustomObject { get; set; }
public DateTime LastLoggedIn { get; set; }
}
public void DoSomething()
{
TempObject temp = new TempObject
{
LoggedInUsername = "test",
SomeCustomObject = //blah blah blah,
LastLoggedIn = DateTime.Now
};
DoSomethingElse(temp);
}
public void DoSomethingElse(TempObject temp)
{
// etc...
}
Usually my temporary objects have a lot more properties, which is the reason I want to group them in the first place. I wish there was an easier way, such as with an anonymous type. The problem is, I don't know what to accept when I pass it to another method. The type is anonymous, so how am I supposed to accept it on the other side?
public void DoSomething()
{
var temp = new
{
LoggedInUsername = "test",
SomeCustomObject = //blah blah,
LastLoggedIn = DateTime.Now
};
// I have intellisense on the temp object as long as I'm in the scope of this method.
DoSomethingElse(temp);
}
public void DoSomethingElse(????)
{
// Can't get my anonymous type here. And even if I could I doubt I would have intellisense.
}
Is there a better way to create a temporary container for a bunch of different types, or do I need to define classes every time I need a temporary object to group things together?
Thanks in advance.
Tuple may be the solution you're looking for.
public void DoSomething()
{
var temp = Tuple.Create("test", "blah blah blah", DateTime.Now);
DoSomethingElse(temp);
}
public void DoSomethingElse(Tuple<string, string, DateTime> data)
{
// ...
}
The rules state that
You cannot declare a field, a property, an event, or the return type
of a method as having an anonymous type. Similarly, you cannot declare
a formal parameter of a method, property, constructor, or indexer as
having an anonymous type.
Personally, I would just bite the bullet on this one to preserve compile time integrity.
The Tuple is the clean way to go, but just to let you know that C# doesn't let you down even otherwise and to answer the question, this is how DoSomethingElse could look like:
private static void DoSomething(object temp)
{
var typedTemp = CastToType(temp, new
{
LoggedInUsername = "dummy",
SomeCustomObject = "dummy",
LastLoggedIn = DateTime.Now
});
Console.WriteLine(typedTemp.LastLoggedIn);
}
private static T CastToType<T>(object obj, T type)
{
return (T) obj;
}
PS: Don't -1, I won't use this, I don't ask you to use this :)
You can pass around anonymous types by declaring the parameter dynamic under C# 4. That said, I would not recommend this except in private methods. You lose type-safety, IntelliSense, and readability.
You could also use non-generic container classes such as ArrayList. But then you're back to casting, which is why we got generics in the first place.
Personally I'd create the class. Look to see if there's an abstraction that covers all your types and declare that as an interface, then use a generic container of that type.
public class GenericObjs
{
private List<object> objs = new List<object>();
public List<object> Objs { get { return objs; } set { objs = value; } }
public GenericObjs(List<object> Objs) { objs = Objs; }
}
You could include List String and a constructor for List String ...
I just don't come across the need for throw away classes. If the business object has structure then a class is the way to define and enforce that structure and it is not much code.

Categories