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;
}
}
Related
I need an attribute that can't be changed after initialisation in the constructor
somthing like this:
private const string banknr;
public ClassName(string banknr)
{
this.banknr = banknr;
//from now on "banknr" can't be changed something like a final or const
}
but it just doesn't work, I realy don't understand
That's precisely what the readonly keyword does.
private readonly string banknr;
public ClassName(string banknr)
{
this.banknr = banknr;
//from now on "banknr" can't be changed something like a final or const
}
readonly variables can be set in a constructor, but can not be changed.
If you want value can't be touched after initialization you can use readonly keyword:
public class Class2
{
public readonly string MyProperty;
public Class2()
{
MyProperty = "value";
}
}
readonly (C# Reference):
You can assign a value to a readonly field only in the following
contexts:
When the variable is initialized in the declaration.
For an instance field, in the instance constructors of the class that contains the field declaration, or for a static field, in the
static constructor of the class that contains the field declaration.
These are also the only contexts in which it is valid to pass a
readonly field as an out or ref parameter.
If you want the value can't be touched out of your class you can use a private setter in a property:
public class Class1
{
public string MyProperty { get; private set; }
public Class1()
{
MyProperty = "value";
}
}
You want readonly instead of const. The difference can be found at http://weblogs.asp.net/psteele/63416. Summary here:
const: only initialized at declaration
readonly: can be initialized at declaration or constructor
Is there a way to modify the access of some attribute to a specific class? More specifically, I want to create a property that has a public get, but can only be set by a certain class.
Example:
public Class1
{
Class2.SomeInt = 5;
}
public static Class2
{
private static int someInt;
public static int SomeInt
{
get { return someInt; }
(give access to Class1 only somehow?) set { someInt = value; }
}
}
Update (more info):
I'm doing this in xna, I want the main type (Game1) to be the only thing that can modify a static helper class. It's for a group project in school, we're using SVN (not sure how that'd be relevant), I could just tell everyone in my group to avoid setting the values, but I was wondering if there was a better way.
This sounds like the friend access modifier, which C# doesn't have. The closest I've seen to this in C# is to have the "unrelated" class be an interface and have a private implementation within a class. Something like this:
public interface IWidget
{
void DoSomethingPublic();
}
public class SomeObject
{
private ObjectWidget _myWidget = new ObjectWidget();
public IWidget MyWidget
{
get { return _myWidget; }
}
private class ObjectWidget
{
public void DoSomethingPublic()
{
// implement the interface
}
public void DoSomethingPrivate()
{
// this method can only be called from within SomeObject
}
}
}
Code external to SomeObject can interact with MyWidget and sees anything that's on the IWidget interface, but code internal to SomeObject can also non-interface public members on MyWidget.
It seems to be impossible in C#. You can only use public, protected, protected internal, internal and private access modifiers.
But you can, for instance, make an assembly that contains only these two classes and set the internal modifier for the SomeInt setter or nest one class into another.
If you want to just hide a setter from the IntelliSense, you can define this setter in some interface and implement it explicitly:
public interface IHidden<T>
{
T HiddenPropery { set; }
}
public class SomeClass : IHidden<int>
{
private int someInt;
public int HiddenPropery
{
get { return someInt; }
}
int IHidden<int>.HiddenPropery
{
set { someInt = value; }
}
}
Usage:
// This works:
((IHidden<int>)new SomeClass()).HiddenPropery = 1;
// This doesn't:
new SomeClass().HiddenPropery = 1;
As far as I know you can can't pass parameters to a static constructor in C#.
However I do have 2 parameters I need to pass and assign them to static fields before I create an instance of a class. How do I go about it?
This may be a call for ... a Factory Method!
class Foo
{
private int bar;
private static Foo _foo;
private Foo() {}
static Foo Create(int initialBar)
{
_foo = new Foo();
_foo.bar = initialBar;
return _foo;
}
private int quux;
public void Fn1() {}
}
You may want to put a check that 'bar' is already initialized (or not) as appropriate.
You can't pass parameters to a static constructor, but you can pass parameters to the class itself - via generic type parameters.
Slightly crazy this idea, however, I'll just throw it out there anyway.
Make the class generic (with a TypeParam that will provide a parameter type) and place generic constraints on it (details in code example), then derive a new parameter type, which contains virtuals that you can use to read what they want the parameter values to be.
//base parameter type - provides the 'anchor' for our generic constraint later,
//as well as a nice, strong-typed access to our param values.
public class StaticParameterBase
{
public abstract string ParameterString{ get; }
public abstract MyComplexType ParameterComplex { get; }
}
//note the use of the new() generic constraint so we know we can confidently create
//an instance of the type.
public class MyType<TParameter> where TParameter:StaticParameterBase, new()
{
//local copies of parameter values. Could also simply cache an instance of
//TParameter and wrap around that.
private static string ParameterString { get; set; }
private static MyComplexType ParameterComplex { get; set; }
static MyType()
{
var myParams = new TParameter();
ParameterString = myParams.ParameterString;
ParameterComplex = myParams.ParameterComplex;
}
}
//e.g, a parameter type could be like this:
public class MyCustomParameterType : StaticParameterBase
{
public override string ParameterString { get { return "Hello crazy world!"; } }
public override MyComplexType { get {
//or wherever this object would actually be obtained from.
return new MyComplexType() { /*initializers etc */ };
}
}
}
//you can also now derive from MyType<>, specialising for your desired parameter type
//so you can hide the generic bit in the future (there will be limits to this one's
//usefulness - especially if new constructors are added to MyType<>, as they will
//have to be mirrored on this type as well).
public class MyType2 : MyType<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
I did consider a solution that employs custom type attributes applies to a type parameter, however this is easily a better way. However, you'll now be using your class always with a generic parameter type (unless you can use the deriving+specialisation trick) - possibly too clumsy for your liking.
I'd also prefer this over the other solutions presented here as it doesn't require creating any workarounds for the static initialisation - you can still use .Net's guarantee of single-time initialisation.
A word of warning - should you be reviewing your structure?
All that said - remember, though, since you can only parameterise the static once (or in this case, each uniquely parameterised static generic) - I would be asking myself why not just pull the code that is getting the parameters to give to the static, and place it in the static constructor in the first place? That way you don't actually have to resort to strange patterns like this!
I assume you mean static members of a class? In that case, you can do this:
public class MyClass
{
public static int MyInt = 12;
public static MyOtherClass MyOther = new MyOtherClass();
}
Those static members are guaranteed to be instantiated before any class is instantiated.
If you need complex logic, do it in a static constructor:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
static MyClass()
{
MyInt = 12;
MyOther = new MyOtherClass();
}
}
Edit
Based on your edit, I'd say just assign the values to what they need to be before you instantiate the class, like so:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
}
// elsewhere in code, before you instantiate MyClass:
MyClass.MyInt = 12;
MyClass.MyOther = new MyOtherClass();
MyClass myClass = new MyClass();
That said, this method gives you no guarantee that MyInt and MyOther are set before MyClass is instantiated. It will work, but requires discipline before instantiating MyClass.
One alternative pattern you might follow looks like this:
public class MyClass
{
private static int MyInt;
private static MyOtherClass MyOther;
private static bool IsStaticInitialized = false;
public static InitializeStatic(int myInt, MyOtherClass other)
{
MyInt = myInt;
MyOther = other;
IsStaticInitialized = true;
}
public MyClass()
{
if(!IsStaticInitialized)
{
throw new InvalidOperationException("Static Not Initialized");
}
// other constructor logic here.
}
}
// elsewhere in your code:
MyClass.InitializeStatic(12, new MyOtherClass());
MyClass myClass = new MyClass();
// alternatiavely:
MyClass myClass = new MyClass(); // runtime exception.
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.
In C# can a constant be overridden in a derived class? I have a group of classes that are all the same bar some constant values, so I'd like to create a base class that defines all the methods and then just set the relevant constants in the derived classes. Is this possible?
I'd rather not just pass in these values to each object's constructor as I would like the added type-safety of multiple classes (since it never makes sense for two objects with different constants to interact).
It's not a constant if you want to override it ;). Try a virtual read-only property (or protected setter).
Read-only property:
public class MyClass {
public virtual string MyConst { get { return "SOMETHING"; } }
}
...
public class MyDerived : MyClass {
public override string MyConst { get { return "SOMETHINGELSE"; } }
}
Protected setter:
public class MyClass {
public string MyConst { get; protected set; }
public MyClass() {
MyConst = "SOMETHING";
}
}
public class MyDerived : MyClass {
public MyDerived() {
MyConst = "SOMETHING ELSE";
}
}
Unfortunately constants cannot be overridden as they are not virtual members. Constant identifiers in your code are replaced with their literal values by the compiler at compile time.
I would suggest you try to use an abstract or virtual property for what you would like to do. Those are virtual and as such can (must, in the case of an abstract property) be overridden in the derived type.
Constants marked with const cannot be overridden as they are substituted by the compiler at compile time.
But regular static fields assigned to constant values can. I've had such a case just now:
class Columns
{
public static int MaxFactCell = 7;
}
class Columns2 : Columns
{
static Columns2()
{
MaxFactCell = 13;
}
}
If I just redefined the MaxFactCell field in the derived class instead, polymorphism wouldn't work: code using Columns2 as Columns would not see the overriding value.
If you need to restrict write (but not read) access to the field, using readonly would prohibit redefining it in Columns2. Make it a property instead, that's slightly more code:
class Columns
{
static Columns()
{
MaxFactCell = 7;
}
public static int MaxFactCell { get; protected set; }
}
class Columns2 : Columns
{
static Columns2()
{
MaxFactCell = 13;
}
}
Edit: This can have unexpected behaviour, see Shai Petel's remark below.
You can hide the inherited constant in a derived class by declaring the new constant new. I'm not sure this is a good practice, though.
class A
{
protected const int MyConst = 1;
}
class B : A
{
new private const int MyConst = 2;
}
to Work off dten + Tracker1's answer but updated for c# 6
public class MyClass {
public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
public override string MyConst =>"SOMETHING ELSE";
}
You can force derived classes to have a value for a constant (well, a read-only property)
Make an interface containing a read-only property.
Put that interface on the base class.
Example:
public interface IHasConstant
{
string MyConst { get; }
}