How can this code compile? The code below in the operator int CAN access a private variable of the class MyValue? Why?
class Program
{
static void Main(string[] args)
{
Myvalue my = new Myvalue(100);
Console.WriteLine(my + 100);
Console.Read();
}
}
public class Myvalue
{
private int _myvalue;
public Myvalue(int value)
{
_myvalue = value;
}
public static implicit operator int(Myvalue v)
{
return v._myvalue;
}
}
Because it is in the class, it has access to private variables in it. Just like your instance public methods. It works the opposite way too. You can access private static members from instance members to create a Monostate pattern.
The private means private for the class and not private for the instance.
operator int() is still a member function of the MyValue class and so can access all fields of objects of type MyValue.
Note that the static just means that a MyValue object needs to be passed to the function as a parameter.
Related
Static members can't be called with instance, like instance.myStaticProperty.
Is there any way, that I can have an instance variable that will be an alias of static self class? like:
class myClass
{
public string a ="hello";
public static string b ="world";
public myClass myVariable = global::myClass; // <--- phseudo code
}
and i could call:
myClass instance= new myClass();
instance.myVariable.b; //
No, there is not. The closest you get is using a using.
Your static class definition:
class ClassA
{
public static string A = "A";
}
And to use it:
using StaticClassA = ConsoleApp1.ClassA;
class Program
{
static void Main(string[] args)
{
string a = StaticClassA.A;
}
}
Not too much to gain though, but it might ease your naming a little.
Another (somewhat cooler) option is a static using:
using static ConsoleApp1.StaticClassA;
class Program
{
static void Main(string[] args)
{
string a = A;
}
}
You're attempting to do an anti-pattern there.
Static properties are properties not defined in an instance (object) of that class, but by the class itself. And as such, you can access and modify them whenever you choose to, provided you have the required scopes to do so.
I don't see the problem in calling MyClass.StaticProperty = <some expression>, if indeed the functions the static property do, are static. If it's something part of the object, something you don't connect with the class itself, i.e it might be different for each instanced object of that class, then just turn it into a regular property instead.
Example of some static properties and methods:
public class DoMath
{
public static string Pi { get; private set; } = "3.14";
public static double X {get; set;}
public static double Y {get; set;}
public static double Sum() => X + Y;
}
DoMath.X = 3.5;
DoMath.Y = 4;
double result = DoMath.Sum();
Console.WriteLine($"Pi is equal to {DoMath.Pi}.");
If you truly wish something to be static, then don't try to make it non-static. Simply declare it as such.
Static members are shared across all instances of the class or all instances of Class Of T of same T.
So you can access static properties outside of class by using the ClassName.VarName or directly by the VarName from within the class.
You can access static fields and properties and methods from all non static methods.
You can also add an instance member mapping a static member.
Instances of a static thing can't exist in addition to the static existence itself.
So you can write this:
class myClass
{
public string a = "hello";
static public string b = "world";
public string B { get { return b; } set { b = value; } }
public void DoSomething()
{
b = "new world";
}
}
And use it like that:
myClass instance= new myClass();
instance.DoSomething();
myClass.b = "another world";
instance.B = "C# world";
Consider the following classes
class A
{
public static int i;
}
class B
{
public static A a{get;}=new A(); // without new A(), B.A will be null
}
now,
B.a gives a new instance of A and since the variable "i" of class A is static, I can not access "i" through B.a i.e B.a.i is compile time error.
I understand that if I do like below,
class B
{
static class A
{
static int i;
}
}
then I could do B.A.i.
So my question is how could I access static members of a static member of a class? Is it possible at all and is there any other pattern that I can use.
Also note that making class "A" as static and having class "B" as
class B
{
public static A a{get;}
}
gives a compile time error that "static type cannot be used as return type".
Since i is static member of A you can access it directly like
class B
{
public static A a {get;} = new A();
public int ii{get;} = A.i;
}
how could I access static members of a static member of a class?
If something is a member of a class -- static or not static -- that means it's either a value or a reference to an instance of something. Therefore, if you know you have an instance of a class but that class has static members itself, then just access those members statically:
class MyClass
{
public static string Value { get; }
}
string x = MyClass.Value;
You don't need to instantiate a class to access it's static members.
Simply you can try :
int value = A.i;
If you need, you can add a static class too :
public static class A
{
public static int i;
}
and you can use anywhere in your code like :
int value = A.i;
For example if we have class MyClass with private field. Is it possible to set value via class object.
public class MyClass { private int field; }
public class Program
{
public static void Main()
{
MyClass cl = new MyClass();
cl = 10; // set value
}
}
It's not directly possible like that in C#, but it's possible to do it through implicit operator overloading by instantiating the class from a value.
public class MyClass
{
private int field;
public static implicit operator MyClass(int value)
{
return new MyClass { field = value };
}
}
Which you can then use like:
MyClass myClass = 100;
That's the closest you will get to what you want.
Other than that you can really only do it through constructors or reflection.
No. But you can expose a method that set the value.
private int _field;
public void SetMyPrivateField(int val)
{
_field = val;
}
or you can take pass the value in with the constructor
public class MyClass
{
private int _field;
public MyClass(int val)
{
_field = val;
}
}
Is it possible to set value via class object.
It is indeed possible to do this using reflection:
public class Program
{
public static void Main()
{
MyClass cl = new MyClass();
var fi = cl.GetType().GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
fi.SetValue(cl, 10);
Console.WriteLine(fi.GetValue(cl));
}
}
But there is probably a reason for the field being private so you shouldn't do this. But you can.
This violate Object Oriented concepts which used in C#
so, you shouldn't do that and save encapsulation concept
by using
Property
public Get{get=>field;set=>field=value;}
Setter & Getter
Constructor
public MyClass(int field) {this.field = field;}
It really depends on how much encapsulation you want to use. Realistically the best way to think about this is to go for the way that limits the accessibility of the variable as much as possible.
You want a variable/property to be read/write outside of the class
Use a public property. This gives you read and write access. There is no need for a backing variable as it's all readable/writeable anyway.
public MyClass
{
public int Field {get; set;}
}
You want a variable/property to be readable outside of the class, but not writeable
There is a couple of ways to skin a cat here. One way is to still use a property but make the setter private, meaning it can only be set inside the class.
public MyClass
{
public int Field {get; private set;}
public MyClass(int field)
{
Field = field;
}
}
I prefer to have a backing readonly variable if it's only to be set inside the constructor and it will never change.
public MyClass
{
private readonly int _field;
public int Field {get=>_field;}
public MyClass(int field)
{
_field = field;
}
}
You want a variable to be passed into a class but not readable/writeable from that point
You should just use a private readonly variable.
public MyClass
{
private readonly int _field;
public MyClass(int field)
{
_field = field;
}
}
I understand how in C# closures allow access to private variables declared in the same scope as an anonymous method, so that those variables are available when the method is invoked in a different scope.
But what about private constructors? This code works:
class Program
{
static void Main(string[] args)
{
var someClassFactory = SomeClass.GetFactoryMethod();
var someclass = someClassFactory();
}
}
class SomeClass
{
private SomeClass()
{
}
public static Func<SomeClass> GetFactoryMethod()
{
return () => new SomeClass();
}
}
As the compiler creates a class for the closure, how does it then reference the private constructor, or otherwise allow it to be accessed when the anonymous method is invoked by the client code?
In this case, the compiler doesn't need to create a class at all - it can just create a static method:
public static Func<SomeClass> GetFactoryMethod()
{
return __GeneratedMethod;
}
private static SomeClass __GeneratedMethod()
{
return new SomeClass();
}
Even when it does need to generate a class - e.g. if GetFactoryMethod() had a parameter which was captured by the lambda expression - it would generate a nested class, and nested classes have access to the private members of their enclosing classes:
public class Foo
{
private Foo() {}
public class Bar
{
public Foo MakeNewFoo()
{
return new Foo(); // This is absolutely fine
}
}
}
I'm just getting curious about the following code :
public static class Container<T>
{
public static readonly T[] EmptyArray = new T[0];
}
As I've understood the static class Container will be initialized when the following code executes:
...
var emptyArray = Container<int>.EmptyArray;
...
Am I right ? Any explanations on static generic classes/members initialization would be appreciated. Thanks in advance.
The guarantee is that the static field is initialized before you access it. (And also, if there is also a static constructor, then all static fields will be initialized before the static constructor is run.)
For generic classes, static initialization works on a per-type basis, so Container<int> acts as if it is a completely different class to Container<double>. This is actually true for all static parts of a generic class - each type gets its own 'copy'.
An example will show this last point more clearly:
static class Foo<T>
{
static int count = 0;
public static int Increment()
{
return ++count;
}
}
public class Program
{
public static void Main()
{
Console.WriteLine(Foo<int>.Increment());
Console.WriteLine(Foo<int>.Increment());
Console.WriteLine(Foo<double>.Increment());
}
}
Output:
1
2
1
Static field initializers are really moved into the static constructor (type initializer) of the class. So your code compiles into this automagically:
public static class Container<T>
{
public static readonly T[] EmptyArray;
static Container()
{
EmptyArray = new T[];
}
}
From MSDN about static constructors:
It [Static Constructor] is called automatically before the first instance is created or any static members are referenced.
Since Container<string> and Container<bool> are not the same, the static constructor is called once for each type of T.