This question already has answers here:
Is there a way of setting a property once only in C#
(14 answers)
Closed 8 years ago.
I have a variable in a class which must have a const value.
private string query;
The value of query can be set only after constructor call. The class is not a static class so there cannot be a Static Constructor with the variable being static readonly like usual. I was wondering can something like below be achieved
private string Query { get; const set;}
or
private string Query { get; static readonly set;}
so that my purpose is solved.
Or
Can I declare the variable normally as
private string query;
and then in the constructor I can make the variable query as const while initializing, i.e., dynamically.
Thanks in advance for any kind of help!!
A member variable/field can not be readonly if it's "set [only] after the constructor call". Neither const or static have any meaning in context of set - and less so than readonly, which still does not apply to properties.
The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
One solution is to use a non-auto property with an explicit backing field and to honor read-only by contract. Other approaches include using a different pattern, including accepting the value in the constructor.
class Foo {
// Only allow this to be set ONCE after the constructor, BY CONTRACT
private string _query;
// No setter, can't assign "accidently"
string Query {
get {
if (_query == null) throw new InvalidOperationException("Query not set");
return _query;
}
// Or maybe just:
// get { return _query; }
}
// Call later on, BEFORE Query is used - but ONLY call once
void BindQuery (string query) {
if (query == null) throw new ArgumentNullException("query");
if (_query != null) throw new InvalidOperationException("Query already set");
_query = query;
}
}
Leveraging this answer...
https://stackoverflow.com/a/839798/342669
...you could
public class MyClass
{
private readonly _query = new WriteOnce<string>();
public string Query
{
private get { return _query.Value; }
set { _query.Value = value; }
}
}
Related
This question already has answers here:
Associating enums with strings in C#
(38 answers)
Can enums contain strings? [duplicate]
(6 answers)
Closed 1 year ago.
I know enums can't be strings
I would like a data structure with the utility of an enum, but one which returns strings instead of integers. To be clear, I want the return type to be the enum-like type, not string. Basically, I want to be able to force a property to be usable as a string but is only allowed to be set to a value in a defined set of strings. Something like
stringenum Unit {
Pixels = "px",
Inches = "in"
}
class Settings {
public Unit Unit { get; set; }
}
var settings = new Settings() { Unit = Unit.Pixels };
...
unitLabel.Text = settings.Unit;
I've seen some solutions that just create a class with properties that return a certain string. However, I need the return type to be limited to a set, not just any string.
EDIT FOR CLARIFICATION
Consider my previous example in addition to this method:
public void WriteUnit(Unit unit)
{
Console.WriteLine(unit);
}
// Calling
WriteUnit(Unit.Pixels); // Prints "px"
WriteUnit("px"); // ARGUMENT EXCEPTION
This method will throw an ArgumentException if you pass it a string. It only accepts the type. This is specifically what I'm looking for.
As mentioned in the comments, you cannot directly map an enum to a string.
That said, there is nothing preventing you from creating a map of enum to string values, that can only be accessed via the enum. If you maintain the mapping, you can guarantee that the value always exist.
public enum Unit
{
Pixels,
Inches
}
public static class UnitMapper
{
private static readonly Dictionary<Unit, string> _map
= new Dictionary<UserQuery.Unit, string>()
{
{ Unit.Pixels, "px" },
{ Unit.Inches, "in" }
}
public static string GetUnit(Unit unit)
{
return _map[unit];
}
}
Based on your additional comments, this can be combined with a custom user-defined implicit operator to give you the type of functionality you are looking for, although you will still have to call the overridden .ToString() to output a string.
public struct UnitWrapper
{
private readonly string _unitString;
private readonly Unit _unit;
public UnitWrapper(Unit unit)
{
_unit = unit;
_unitString = UnitMapper.GetUnit(_unit);
}
public static implicit operator UnitWrapper(Unit unit)
{
return new UnitWrapper(unit);
}
public override string ToString() => _unitString;
}
This can then be used as follows:
public class Settings
{
public UnitWrapper UnitWrapper { get; set; }
}
var settings = new Settings { UnitWrapper = Unit.Pixels };
string px = settings.UnitWrapper.ToString();
This question already has answers here:
What is difference between Init-Only and ReadOnly in C# 9?
(4 answers)
Closed 1 year ago.
I can define a class like below:
public class MyClass
{
public int Id { get; }
public MyClass(int id) => Id = id;
}
And I have to define the Id from the constructor and it will be read-only.
But if I want to use Init only setters in the C# 9.0, what does it and how can I use it?
public class MyClass
{
public int Id { get; init; }
}
Init only setters provide consistent syntax to initialize members of an object. Property initializers make it clear which value is setting which property. The downside is that those properties must be settable.
With that, you don't need to provide the value at the beginning and the constructor and you can do it afterward:
var myClass = new MyClass
{
Id = 10
}
and it will be sealed and you cannot change it anymore.
myClass.Id = 43; // not allowed
read more info
In a nutshell:
var obj = new MyClass
{
Id = 42 // totally fine
};
obj.Id = 43; // not OK, we're not initializing
Trivial in this case and not much different to using a constructor parameter, but useful in some more complex scenarios where you don't want 200 constructor parameters, but you do want it to be outwardly immutable once constructed.
This question already has answers here:
How to get a property value based on the name
(8 answers)
Closed 2 years ago.
I want to get the value of a desired variable among several variables in a class
When i put string and class in Method, the method returns the value of the variable with the same name as the string received among all variables included in the class.
This method can get any type of class. So this method need to use generic.
Do anyone have a good idea for my problem?
public class A
{
public int valA_int;
public string valA_string;
public float valA_float;
public long valA_long;
}
public class B
{
public int valB_int;
public string valB_string;
public float valB_float;
public long valB_long;
}
public static class Method {
public static object GetvalueFromClass<T>(string varName, T classType) {
//Find val from class
return object;
}
}
public class Program {
public A aClass;
public B bClass;
public void MainProgram() {
object valA_int = Method.GetvalueFromClass("valA_int", aClass);
object valB_long = Method.GetvalueFromClass("valB_long", bClass);
}
}
The concept of method is like this.
please help me to figure out my problem.
your task already defined.
if you use
#{Class}.GetType().GetProperty(#{VariableName}).GetValue(#{DefinedClass}, null);
you can easily get variable from your class with variable name.
it returns variable as object. so you need to convert it
Example code
CLASS YourClass = [A CLASS WHICH IS PRE DEFINED];
object Target = YourClass.GetType().GetProperty("YOUR VARIABLE").GetValue(YourClass , null);
ok, use reflection to get all the variables in the object, then run through a loop checking them against the string of the property name. From there you should be able to return the value.
So something like
public object FindValByName(string PropName)
{
PropName = PropName.ToLower();
var props = this.GetType().GetProperties();
foreach(var item in props) {
if(item.Name.ToLower() == PropName) {
return item.GetValue(this);
}
}
}
This question already has answers here:
Get value of a public static field via reflection
(4 answers)
Closed 4 years ago.
I have a pseudo-enum class that consists of a protected constructor and a list of readonly static properties:
public class Column
{
protected Column(string name)
{
columnName = name;
}
public readonly string columnName;
public static readonly Column UNDEFINED = new Column("");
public static readonly Column Test = new Column("Test");
/// and so on
}
I want to access individual instances by their string name, but for some reason, the reflection does not return the static properties at all:
In the above image, you can see that the property exists and has a non-null value, yet if I query it using reflection, I get null.
If I try to query the property list, I get an empty array:
PropertyInfo[] props = typeof(Column).GetProperties(BindingFlags.Static);
if (props.Length == 0)
{
// This exception triggers
throw new Exception("Where the hell are all the properties???");
}
What am I doing wrong?
You are trying to access fields, not properties.
Change your reflection code to this:
FieldInfo[] fields = typeof(Column).GetFields();
if (fields.Length == 0)
{
// This exception no longer triggers
throw new Exception("Where the hell are all the properties???");
} else
{
foreach (var field in fields)
{
Console.WriteLine(field.Name);
}
}
I have a field which is static and readonly. The requirement is that the value should be allocated to the field at the login time and after that it should be readonly. How can i achieve this ?
public static class Constant
{
public static readonly string name;
}
Kindly guide.
If you declare a readonly field you can only set it in the constructor of the class. What you could do is implementing a property only having a getter and exposing a change method that is used during your logon sequence to modify the value. Other Parts of your program can use the property effectivly not allowing them to change the value.
public static class Constant
{
public static string Name
{
get
{
return name;
}
set
{
if (name == null)
name = value;
else
throw new Exception("...");
}
}
private static string name;
}
you need a static constructor
public static class Constant
{
public static readonly string name;
static Constant()
{
name = "abc";
}
}
Just assign the value in the declaration (or constructor) like this:
public static class Constant
{
public static readonly string name = "MyName";
}
readonly is sugar for the compiler, telling him, that you don't intend to change the value outside the constructor. If you do so, he will generate an error.
You can also create a static constructor in your static class
static Constant()
{
name = "Name";
}