By what logic, should instance constructors have access to static fields - c#

I was wondering why do instance constructor have access to static fields? If I initialize static fields via static constructors, and by mistake again initialize them through instance constructors, then the second initialization overwrites the first one. What is the idea behind making them accessible through instance constructors? (Please have a look at the simple program below to understand my point)
using System;
class Program
{
static void Main()
{
Circle C1 = new Circle(5);
Console.WriteLine("The area of the first circle is {0}", C1.CalculateArea());
}
}
class Circle
{
public static float _Pi; // Since the value of pi will not change according to circles, we have to make it static
int _Radius; // This is an instance field, whose value is different for different instances of the class
static Circle() // A static constructor initializes the static fields
{
Console.WriteLine("Static constructor executed");
Circle._Pi = 3.14F;
}
public Circle(int Radius) // An instance constructor initializes the instance fields
{
Console.WriteLine("Instance constructor executed");
this._Radius = Radius;
Circle._Pi = 2.12F; // This again initializes the value of the pi to a different value as given by the static constructor
}
public float CalculateArea()
{
return this._Radius*this._Radius*Circle._Pi;
}
}

As an example of a use case where a constructor could want access to static members is when a static field contains a counter of instances for a class. You may want a class member to get, retain (in a non-static field), and increment this counter which would be static. Any time in the future that instance will have its own unique identifier.
Example:
public class Employee {
static int NextEmployeeId; // a counter across all employees
public int EmployeeId; // this instance's employee id
public string Name; // this instance's name.
static Employee() {
Employee.NextEmployeeId = 1; // first employee gets 1.
}
public Employee(string Name) {
this.Name = Name;
this.EmployeeId = Employee.NextEmployeeId++; // take an id and increment for the next employee
}
}

Static fields are accessible from everywhere, even from constructor, or even from Main/other class. The purpose is that you will have only one static property/ field singleton for the whole app.
public class AClass()
{
public static float staticField;
public float field;
public AClass()
{
staticField = 5;
field = 6;
}
static AClass()
{
staticField = 7;
}
}
public int Main()
{
float initially = AClass.staticField; // initially this staticField is 7.
AClass aclass = new AClass(); // instantiating AClass
float localfield = aclass.field; // this field does not affect anyone. It is 6
float newStaticField = AClass.staticField; // Due to previous instantiation, the value is now 5.
}
And I agree with you that in your example it is bad. Why? Because why would you change the value of Pi, since it is already determined and fixed, there is no reason to change the value of Pi in the constructor.
You probably need to know how to design class and get to know why you want to have the static field in the first place. Here is an example of a class which does it correctly having a static field (sort of... for example, because the Key should be hidden supposedly. This is just to show you how static field is useful and ok.):
public class NewEncryptionClass()
{
public static string Key;
public NewEncryptionClass()
{
}
public NewEncryptionClass(string newKey)
{
Key = newKey; // store the key and keep it forever
}
static NewEncryptionClass()
{
Key = "key1"; // initially key is "key1"
}
public string Encrypt(string str)
{
string result = string.Empty;
result = "adlasdjalskd" + Key + "ajlajfalkjfa" + str; // do the Encryption, I just made up
return result
}
}
Here, the purpose is that if you instantiate a NewEncryptionClass, you would want to save the key, so that the next time you do the encryption, you would always use the latest key without having to specify it everytime. For ex:
public int Main()
{
string initialkey = NewEncryptionClass.Key;
string result1 = new EncryptionClass().Encrypt("encryptThis"); // using key1
// let's change the key
string result2 = new EncryptionClass("key2").Encrypt("encryptThat"); // using key2
string result3 = new EncryptionClass().Encrypt("encryptOther"); // still using key2
}
This is of course if I want to keep the latest key forever, if not, then this class design is wrong and you need to rewrite it for your purpose.

Related

It is possible to save a variable's reference inside another variable in c#?

I am developing a little console game where you go through a dungeon. I'm trying to make a potion system for it, the idea is that when you use a potion, it changes a specific stat of the player.
The stats of the player are stored in a static class called Stats. I want to create different potions from the same class, and change the stat the potion acts on using its constructor method. The way I want this to work is that, when a new potion instance is created, I pass to the constructor a reference to the stat variable, and the constructor will store that reference in a variable, to use it when the potion is used.
I tried using delegates with getters and setters, but it didn't work because they only work with functions. I can solve this problem making a potion id system, or learning to proper use pointers, but I prefer to use only safe code.
My question is: There is a way in c# to store a reference to a variable in another variable?
The Stats class:
static class Stats{
public static int health = 10,
strenght = 5,
defense = 20;
}
The potion class:
class Potion {
int statRef; //This is the "reference holder" variable I was asking about.
int magnitude;
public Potion(ref int stat, int _magnitude)
{
magnitude = _magnitude;
statRef = stat; //Here I want to save the reference to the stat to the "reference holder"
}
public void UsePotion()
{
statRef += magnitude; //Here I want to change the referenced variable's value.
}
}
The main program:
class Program{
static class Main(string[] args)
{
Potion lifePotion = new Potion(Stats.life, 5);
Potion strenghtPotion = new Potion(Stats.strenght, 5);
Potion defensePotion = new Potion(Stats.defense, 10);
lifePotion.UsePotion();
strenghtPotion.UsePotion();
defensePotion.UsePotion();
Console.WriteLine(Stats.health);
Console.WriteLine(Stats.strenght);
Console.WriteLine(Stats.defense);
}
}
Note that a class is a reference type. So, variables of a class type automatically contain references and you can assign the same reference to another variable. You can only create an object (i.e., an instance of a class) if the class is not static. Then you can assign it to a variable.
The fields or properties must not be static. Non static members are called instance members. Each instance (object) has its own copy of the fields and properties that must be accessed through a variable name. Static members, in contrast, are shared among all objects of this type and must be accesses through the class name.
Stats stats1 = new Stats();
Stats stats2 = stats1;
now both variables reference the same Stats. If you make the change
stats1.health = 5;
then stats2.health is also 5 since both reference the same object. But of course, you can create independent Stats objects:
Stats stats1 = new Stats();
Stats stats2 = new Stats();
Now changes to stats1 do not affect stats2.
Note that an important idea of Object-Oriented Programming (OOP) is that objects should hide their internal state, i.e., their fields. From outside the state should only be accessible through methods. These methods ensure that the state is manipulated in an adequate manner. E.g., it could be ensured that the health stays within a valid range.
Properties are specialized methods allowing to manipulate the state of fields. They usually consist of a pair of get and set methods and can be accessed like a field.
Example:
class Stats
{
private int _health = 10;
public int Health
{
get { // called when reading the value: int h = stats1.Health;
return _health;
}
set { // called when setting the value: stats1.Health = 5;
if (value < 0) {
_health = 0;
} else if (value > 100) {
_health = 100;
} else {
_health = value;
}
}
}
}
If a property has no such logic, you can use an auto implemented property. It automatically creates an invisible backing field (like _health) and returns and sets its value.
public int Health { get; set; }
Let us put the things together. Simple example of Stats class:
class Stats
{
public int Health { get; set; } = 10;
public int Strength { get; set; } = 5;
public int Defense { get; set; } = 20;
}
Now you can reference a Stats object in the Potion class.
Because you want to have different kinds of potions, you can use inheritance (another important concept of OOP) to achieve this.
You can declare an abstract base class, i.e., a class that cannot be instantiated and can itself contain abstract members, i.e., members that have still to be defined in derived classes.
abstract class Potion
{
// This is the "reference holder" variable you were asking about.
protected Stats _stats;
// Protected means private and visible to derived classes.
protected int _magnitude;
public Potion(Stats stats, int magnitude)
{
_stats = stats; // Save the reference to the stat to the "reference holder"
_magnitude = magnitude;
}
public abstract void UsePotion();
}
Now the derived LifePotion class as an example
class LifePotion : Potion // Inherits Potion.
{
public LifePotion(Stats stats, int magnitude)
: base(stats, magnitude) // Calls the base constructor.
{
}
public override void UsePotion()
{
_stats.Health += _magnitude; // Change a property of the referenced variable.
}
}
Repeat the same for StrenghtPotion and DefensePotion classes with UsePotion setting the Strength and Defense properties.
The adapted main program
class Program{
static class Main(string[] args)
{
var stats = new Stats();
Potion lifePotion = new LifePotion(stats, 5);
Potion strenghtPotion = new StrengthPotion(stats, 5);
Potion defensePotion = new DefensePotion(stats, 10);
lifePotion.UsePotion();
strenghtPotion.UsePotion();
defensePotion.UsePotion();
Console.WriteLine(stats.Health);
Console.WriteLine(stats.Strength);
Console.WriteLine(stats.Defense);
}
}
Note that you can override ToString in a class and provide your own implementation. Add this to the Stats class:
public override string ToString()
{
return $"Health = {Health}, Strength = {Strength}, Defense = {Defense}";
}
Then you can print the health like this in the main routine:
Console.WriteLine(stats); // Prints: Health = 15, Strength = 10, Defense = 30
C# is an object-oriented programming language. That means it is designed to use “objects”, or in-memory instances of classes, that are responsible for maintaining their own state. Now you don't have to do this, but the more you stray from this design the less the language supports you, and the more work you have to do yourself.
Your design is not object-oriented. There probably isn't a “stats” that wanders around in your game, statting things. It probably isn't static either. Static classes are for concepts that can't change. For example, Math.Sin is static; its meaning can't change and my Math.Sin is your Math.Sin.
Instead of static Stats wandering around, your game probably has characters or Mooks. So make a class for them:
public class Mook
{
public string Name { get; }
public int Strength { get; private set; }
public Mook(string name, int strength)
{
Name = string.IsNullOrWhiteSpace(name) ? throw new ArgumentNullException(nameof(name)) : name;
Strength = strength;
}
}
Now you can create instances of Mooks:
var player = new Mook("Link", 10);
var monster = new Mook("Orc", 11);
Mooks can do things, like attack or drink potions. Potions can do things, like modifying your strength. Each class is responsible only for its own internal state; you don't have potions changing Mooks, only the Mook themselves can do that. Classes do things that change themselves through methods. If you want a Mook to drink a potion you have to create a method inside your Mook class to do that:
public void Drink(Potion potion)
{
switch (potion.Sipped())
{
case PotionEffect.ModifyStrength:
Strength += potion.Modifier;
break;
}
}
Potions don't decide what happens outside themselves, only the class using the potion does. To track the possible effects of a potion, create an enum:
public enum PotionEffect
{
Nothing,
ModifyStrength
}
Potions are other objects, so you need to create another class. Remember, each class is responsible for maintaining its own state:
public class Potion
{
public PotionEffect Effect { get; }
public int Modifier { get; }
public int Doses { get; private set; }
public Potion(PotionEffect defaultEffect, int modifier, int doses)
{
Effect = defaultEffect;
Modifier = modifier;
Doses = doses;
}
public PotionEffect Sipped()
{
if (Doses <= 0)
return PotionEffect.Nothing;
Doses--;
return Effect;
}
}
Now you can create potions:
var strengthPotion = new Potion(PotionEffect.ModifyStrength, +1, 10);
And have mooks drink them:
player.Drink(strengthPotion);
monster.Drink(strengthPotion);

For what do you need "this." in c# [duplicate]

This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 5 years ago.
The older apprentices in my company use "this." a lot.
Two weeks ago I started coding object-oriented and still don't get for what it is being used.
You need to understand what instance is first. Let's say you have an object:
public class House
{
public decimal Height { get; set; }
}
You can have multiple instances of it:
var smallHouse = new House { Height = 100M };
var bigHouse = new House { Height = 300M };
Each instance has its own value of Height. When you want to work with Height in a method of House, you need to refer to the current instance method is operating at (the one consumer called).
This can be done explicitly by using this as a special kind of variable that refers to this current instance:
public class House
{
public decimal Height { get; set; }
public bool IsItTooBig()
{
return this.Height > 200;
}
}
Or you can omit this and let C# guess that what you mean is the instance value:
public class House
{
public decimal Height { get; set; }
public bool IsItTooBig()
{
return Height > 200;
}
}
Programmers differ in opinion whether it's good or bad to be explicit there. If you follow capitalization conventions, you can distinguish instance state and method scope state (normal variables) by it.
There are cases where you absolutely need it, for example when you have naming conflict, or when you want to return current instance from a method:
public class House
{
public decimal Height { get; set; }
public House AddFloor()
{
Height += 100;
return this;
}
}
You should consider applying immutability in many of these cases though.
The keyword 'this' represents the instance of an object used to explicitly call a method, field or property of that instance.
Commonly used when your private fields have the same name as the parameters in a given method:
private string name;
public void SetName(string name) {
this.name = name;
}
When you want to refer to instance field within that class you use this, it can be omitted but there are cases it can not be omitted.
public class InstanceClass
{
int field = 10;
public void Method()
{
int field = 0;
Console.WriteLine(field); // outputs 0
Console.WriteLine(this.field); // outputs 10 because "this" refers to field.
}
}
if there is no declared local variable that conflicts with field name, "this" can be omitted.
public class InstanceClass
{
int _field = 10;
public void Method()
{
int field = 0;
Console.WriteLine(field);
Console.WriteLine(_field); // prefixed with _.
// no conflicts
// so "this" can be omitted.
}
}
another case where you can not omit this, is when you use indexer.
public class InstanceClass
{
private List<int> _source;
private int offset;
public int this[int index] // you use "this"
{
get => _source[index + offset]
set => _source[index + offset] = value;
}
public void Method()
{
var first = this[0]; // must use "this" to refer to indexer for this class.
}
}
"this" is used for calling constructor overloads too.
public class Foo
{
public Foo() : this(0)
{
Console.WriteLine("world");
}
public Foo(int param1)
{
Console.WriteLine("Hello");
}
}
//...
var foo = new Foo(); // outputs "Hello world"
"this" also refers to instance of class itself. so if you want to return instance of self you use this.
public class Foo
{
public Foo ReturnMe() // weird example.
{
return this;
}
}

get set property usage

I am a bit confused with the get set property in C#.
I have the simple code below:
using System;
class Example
{
int _number;
public int Number
{
get
{
return this._number;
}
set
{
this._number = value;
}
}
}
class Program
{
static void Main()
{
Example example = new Example();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
The code above using get set properties. However, if I delete the get set code like below code, the results stay the same.
using System;
class Example
{
int _number;
public int Number;
{
}
}
class Program
{
static void Main()
{
Example example = new Example();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
My query is, what is the get set code used for? In the above program, the results are same. Can you give me some simple code which show the get set usage?
In your code, Number is simply a public field, as evidenced by the semicolon (;) at the end.
public int Number;
It is not a property, you just have an empty set of brackets right underneath which led to your confusion. If you were to remove the ; then you would actually have a property that is missing it's get, and would not compile at all.
All properties need to have a getter (setters are optional). If you want to avoid writing them, you can use auto properties, which take care of the backing field without you having to get involved:
public int Number { get; set; } // No field required
Note: A common usage pattern you'll see involving auto properties is the following:
public int Number { get; private set; }
This allows for properties that can be read from anywhere, but can only be modified from within the class they belong to.
EDIT: To answer your question, the main difference between fields and properties is in encapsulation. You can read more about the general differences between fields and properties here.
However, the example you have given has one additional difference, the private set. A normal field can be written from and to throughout the program. A property with a private setter however can only be modified from inside the class it belongs to.
Example:
public class Foo
{
public int Id { get; private set; }
public string Name;
public Foo()
{
this.Id = 1; // This works!
}
}
Here, Name is a field and Id is a property with a private setter. Notice that we modify Id in the constructor and that works, because it is within the class Id belongs to. Moving outside the class however:
var foo = new Foo();
// Field (no get and set):
foo.Name = "test" // Works
string bar = foo.Name; // Works
// Property (get and *private* set)
int i = foo.Id; // Works, because get is public
foo.Id = 2; // Doesn't work, because set is private

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;
}
}
}

knowing get;set in c#

I am writing following code,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReadOnlyObject
{
class Program
{
private readonly int a = 20;
private readonly int b;
public int propa{get;private set;}
public int propb { get; private set; }
public Program(int tmp)
{
b = tmp;
}
static void Main(string[] args)
{
Program obj1 = new Program(30);
Console.WriteLine(obj1.propa); // Console.WriteLine(obj1.a);
Console.WriteLine(obj1.propb); // Console.WriteLine(obj1.b);
Console.Read();
}
}
}
After executing the above i got o/p as follows,
0
0
And when I change the code by replacing two commented statements printing direct member variables I got output as,
20
30
Why is so?
As far I know about properties they are associated with their definition in order the member variables are declared.
You have confusion about auto property, so:
private readonly int a = 20;
private readonly int b;
public int propa{get {return a; }}
public int propb { get {return b;} private set {b = value;} }
now this will print 20, 30
There are two ways to define properties in C#.
The first, the traditional way;
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
the second, the auto-property;
public int MyProperty {get;set;}
The first contains a backing variable that you reference in the property accessor. The second implicitly creates a backing variable, because the developers of the language understood that there are a lot of cases where you just need a property!
You can put scope on the auto-property, because you might want to prevent people from setting the value, but internally to the object you should be able to update the value of it.
"As far I know about properties they are associated with their
defination in order the member variables are declated."
Just to clarify all of what you were asking, unless I am reading this statement incorrectly, you're thinking that if you declare variable a and b and the property a and property b that they'll be associated. This is an incorrect assumption.
propa and a are not associated in your example. The compiler is making them auto-implemented properties. http://msdn.microsoft.com/en-us/library/bb384054.aspx If you want propa associated with a then you'd do:
public int propa{get { return a;} }
You're not initializing either property. You also can't set the value of b from a setter if it's marked readonly. You can implement your own 'readonly' type by just not letting the value get set more than once. (Although it doesn't stay true to the constraint that it needs to be initialized in the constructor)
Try this:
private readonly int a = 20;
public int A { get { return a; } }
private int b;
private bool bInitialized = false;
public int B
{
get { return b; }
private set
{
if (bInitialized) return;
bInitialized = true;
b = value;
}
}
The way your code is written propb and propa CANNOT be set outside the scope of the class. so remove the keyword private from the set keyword
if you wrote this.propb = b in your constructor, then I think it should work more like you are expecting.

Categories

Resources