Reflection doesn't show static properties properly [duplicate] - c#

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

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

Readonly Field used as a normal field [duplicate]

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

How to get value of variable from selected class In c#? [duplicate]

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

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

How to get class members values having string of their names? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I read the properties of a C# class dynamically?
I have to get values of class members using strings of their names only. I think I have to use Reflection but I am not realy sure how to. Can you help me?
MemberInfo member = typeof(MyClass).GetMember("membername");
GetMember reference.
If you know type of member you're looking for, you can use .GetMethod, .GetField, .GetProperty, etc.
If you don't know the type you are working with:
var myobject = someobject;
string membername = "somemember";
MemberInfo member = myobject.GetType().GetMember(membername);
Different member types have different means to getting the value. For a property you would do:
var myobject = someobject;
string propertyname = "somemember";
PropertyInfo property = myobject.GetType().GetProperty(membername);
object value = property.GetValue(myobject, null);
public class Foo
{
public string A { get; set; }
}
public class Example
{
public void GetPropertyValueExample()
{
Foo f = new Foo();
f.A = "Example";
var val = f.GetType().GetProperty("A").GetValue(f, null);
}
}

Categories