Readonly Field used as a normal field [duplicate] - c#

This question already has answers here:
Are C# readonly field's allowed to be modify outside of the class?
(3 answers)
Prevent other classes from altering a list in a class
(4 answers)
Closed 1 year ago.
I was checking an online tutorial video and I noticed this code modifying a readonly field without constructor and it was working fine. How & Why it works?
public class Journal
{
private readonly List<string> entries = new List<string>();
private static int count = 0;
public int AddEntry(string text)
{
entries.Add($"{++count}: {text}");
return count; // memento pattern!
}
public void RemoveEntry(int index)
{
entries.RemoveAt(index);
}
public override string ToString()
{
return string.Join(Environment.NewLine, entries);
}
}
public class Demo
{
static void Main(string[] args)
{
var j = new Journal();
j.AddEntry("I cried today.");
j.AddEntry("I ate a mango.");
WriteLine(j);
}
}
output:
I cried today.
I ate a mango.

What is really happening here is that a method called on the entries readonly field and it Does NOT change the reference of the entries field.
Changing the reference of the readonly field is a compile error, but calling a method on the readonly (whatever it does internally) has no problem at all
Try the following statement
entries = new List<string>();
and you will see the error

Related

How can I make a strongly typed set of string values? [duplicate]

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();

Providing Access to a Class Private Member Attributes [duplicate]

This question already has answers here:
Properties vs Methods
(16 answers)
Closed 4 years ago.
I was wondering what is more efficient or the best practice for returning attributes of private members. For example:
class Foo
{
private List<int> fooList;
public Foo()
{
Random random = new Random();
fooList = new List<int>(random.Next(1, 100));
}
//
public int Count { get { return fooList.Count; } }
// or
public int Count() { return fooList.Count; }
}
Which is best if I do not want to give public access to my list?
Based on your example, you should stay with a property. Because the fooList.Count is a property.

Reflection doesn't show static properties properly [duplicate]

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

Const set property in C# [duplicate]

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

Redefine static fields in derived / nested classes in C# [duplicate]

This question already has answers here:
Why can't I declare C# methods virtual and static?
(16 answers)
Closed 9 years ago.
i have a class with a static field and a static function, e.g. like this
public class A {
protected static string[] _eventField = new[] { "SomeValue" };
public static TOut DoSomethingThatDependsOnEventField(TIn input){
//output depends on input and the static _eventField
}
public class Nested1: A {
protected new static string[] _eventField = new[] { "SomethingDifferent" };
}
public class Nested2 : A {
protected new static string[] _eventField = new[] { "SomethingElse" };
}
}
The output and input types of that static method are of no importance here, the only relevant thing is that the output - despite relying on the input, of course - depends on the content of the static field. The implementation of the method doesn't change at all in the derived classes, and all I want is to change that very static field. But whenever I do a call like
var res1 = A.Nested1.DoSomethingThatDependsOnEventField(...);
or
var res2 = A.Nested2.DoSomethingThatDependsOnEventField(...);
the incorrect static field from the base class A is referenced from within the method.
That is, the intended "hiding" / "redefining" of the static field via protected new static string[] _eventField = ... doesn't work - Why is that so?
You cant have an object associated with Static field/member/function , so static field/member/function cannot come into picture in Inheritance also.

Categories