Need explanation for some code. - c#

What does
public object this[string name]
do
class ObjectWithProperties
{
Dictionary<string, object> properties = new Dictionary<string, object>();
public object this[string name]
{
get
{
if (properties.ContainsKey(name))
{
return properties[name];
}
return null;
}
set
{
properties[name] = value;
}
}
}

You will be able to reference the values in your dictionary directly from your object using indexes (ie, no property name)
In your case it would be
var foo = new ObjectWithProperties();
foo["bar"] = 1;
foo["kwyjibo"] = "Hello world!"
// And you can retrieve them in the same manner...
var x = foo["bar"]; // returns 1
MSDN guide: http://msdn.microsoft.com/en-gb/library/2549tw02.aspx
Basic tutorial: http://www.tutorialspoint.com/csharp/csharp_indexers.htm
Edit to answer question in comment:
This is equivalent to doing something like the following:
class ObjectWithProperties
{
public Dictionary<string, object> Properties { get; set; }
public ObjectWithProperties()
{
Properties = new Dictionary<string, object>();
}
}
// instantiate in your other class / app / whatever
var objWithProperties = new ObjectWithProperties();
// set
objWithProperties.Properties["foo"] = "bar";
// get
var myFooObj = objWithProperties.Properties["foo"]; // myFooObj = "bar"

Related

How can i add a property to object during the a run time at C#?

I have two different lists. I want to combine these list in an object. I don't know the property names in these lists, which is why I cannot create a class in advance.
public class exampleConfigProperty
{
public string PropertName { get; set; };
public string PropertValue { get; set; };
}
public class exampleFile
{
public string config1 { get; set; };
}
List<exampleConfigProperty> myList = new List<exampleConfigProperty>();
myList.add(new exampleConfigProperty {
PropertName = "Config_Property_Name",
PropertValue = "Config Property Value"
});
List<exampleFile> myListTwo = new List<exampleFile>();
myListTwo.add(new exampleFile {
config1 = "Config Value"
});
I tried to figure out if is there any way I can use the code below:
var obj = new object();
foreach(var item in myList)
{
obj.addProperty(item.PropertName, item.PropertValue );
}
foreach(var item in myListTwo)
{
obj.addProperty(nameof(item.config1), item.config1 );
}
In conclusion I try to create an object instance by using two lists,
for example:
var resut = new {
Config_Property_Name = "Config Property Value",
config1 ="Config Value"
}
dynamic type does not work so what should I do to get an object instance by using two lists?
Since you just want to make a JSON I think would fit your criteria:
var test = new Dictionary<string, string>(); //<string, object> for mixed types of values
test["key1"] = "value1";
test["key2"] = "value2";
var result = JsonConvert.SerializeObject(test); //indented for readability of result
// result:
// {
// "key1": "value1",
// "key2": "value2"
// }

C# Reflection Get List of Object

I have a problem fetching object from the array object that I made. It seems it didn't fetch the object see my code below:
Product Model
public class Product
{
public string Id { get; set; }
public List<ExcelName> ShortDesc { get; set; } // I want to get the object from here
}
Short Description Model
// get this object and the properties inside it.
public class ExcelName
{
public string Name { get; set; }
public string Language { get; set; }
}
My Code
private static T SetValue<T>(Dictionary<string, object> objectValues)
{
var type = typeof(T);
var objInstance = Activator.CreateInstance(type);
if (!type.IsClass) return default;
foreach (var value in objectValues)
{
if (value.Key.Contains(":Language="))
{
var propName = value.Key.Split(':')[0];
// propName is ShortDesc object
var propInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name.ToLower() == propName.ToLower().Replace(" ", ""));
if (propInfo == null) continue;
if (propInfo.PropertyType.IsGenericType)
{
// I want to get the type and properties from T generic using reflection instead static
var name = typeof(ExcelName);
var excelNameObjectInstance = Activator.CreateInstance(name);
foreach (var propertyInfo in name.GetProperties())
{
propertyInfo.SetValue(excelNameObjectInstance, value.Value, null);
}
// add excelNameObjectInstance object to the list in ShortDesc
}
}
}
}
How to fetch the object from the list of ShortDesc to get the ExcelName objects.
I'm not quite sure what you're trying to do, but it seems like you want a function that instantiates a T and sets its properties according to a dictionary.
Half your code doesn't make sense to me, but my guess is correct, you shouldn't need anything more complicated than this:
private static T SetValue<T>(Dictionary<string, object> objectValues) where T : class, new()
{
var type = typeof(T);
var instance = new T();
foreach (var entry in objectValues)
{
type.GetProperty(entry.Key).SetValue(instance, entry.Value);
}
return instance;
}
If you don't expect the keys to be an exact match for property names, you can introduce a normalization function:
private static string Normalize(string input)
{
return input.ToLower().Replace(" ", "");
}
private static T SetValue<T>(Dictionary<string, object> objectValues) where T : class, new()
{
var type = typeof(T);
var instance = new T();
foreach (var entry in objectValues)
{
var prop = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.First( x => Normalize(x.Name) == Normalize(entry.Key) );
prop.SetValue(instance, entry.Value);
}
return instance;
}

is it possible to access properties by name, which is a variable?

Sorry if this is asked and answered, I searched but think I don't know the vocabulary to find the answer. Researched reflection but that doesn't seem to be the answer here? I'm a novice obviously. I'm trying/making minor contributions to a mod for the new Battletech game.
I've got this Dictionary and would like to use its keys to set properties as in the foreach below. I don't know if this is at compile or runtime, my guess is compile time...
I put *limb* in as pseudo-code for how I'm imagining it might work. The property mechDef.Head is an object of type LocationLoadoutDef with its property CurrentInternalStructure being float.
Hope that makes sense!
Much obliged for any assistance.
public class Settings {
public readonly Dictionary<string, bool> LimbRepair = new Dictionary<string, bool> {
{ "Head", false },
{ "LeftArm", false },
{ "RightArm", false },
{ "CenterTorso", false },
{ "LeftTorso", false },
{ "RightTorso", false },
{ "LeftLeg", false },
{ "RightLeg", false },
};
}
MechDef mechDef = new MechDef
(__instance.DataManager.MechDefs.Get(id), __instance.GenerateSimGameUID());
foreach (string limb in settings.LimbRepair.Keys) {
if (!settings.LimbRepair[limb]) {
mechDef.*limb*.CurrentInternalStructure = Math.Max
(1f, mechDef.*limb*.CurrentInternalStructure * (float)rng.NextDouble());
}
You can do it with Reflection, but....
This is quite easy to do with Reflection, and you'll probably get a couple answers on here that show you how, but since you are writing a game, I'm guessing you want the best performance possible, and Reflection isn't always going to give you that.
Below is a solution that requires no reflection but still allows you to use the loop structure you want. It just requires a little bit of setup when you create the object, then you can access your properties as if they were in a dictionary.
Solution: Use a dictionary of delegates to map the properties
First we need to write a utility class that represents a property. Since properties can be different types, this is a generic class with a type argument.
class PropertyWrapper<T>
{
private readonly Func<T> _getter;
private readonly Action<T> _setter;
public PropertyWrapper(Func<T> getter, Action<T> setter)
{
_getter = getter;
_setter = setter;
}
public T Value
{
get
{
return _getter();
}
set
{
_setter(value);
}
}
}
The idea behind this class is that you create it to represent any property you want, and call its methods to read and set the property. The class knows how to read and set the property because you tell it how, when you construct it, by passing it a short lambda expression that does the work.
This utility will allow you to put all the properties that represent limbs into a dictionary. Then you can look them up by string, just like your settings. So for example your MechDefinition might look like this:
class MechDef
{
public Limb Head { get; set; }
public Limb LeftArm { get; set; }
public Limb RightArm { get; set; }
public Limb LeftTorso { get; set; }
public Limb RightTorso { get; set; }
public Limb CenterTorso { get; set; }
public Limb RightLeg { get; set; }
public Limb LeftLeg { get; set; }
private readonly Dictionary<string, PropertyWrapper<Limb>> Properties;
public MechDef()
{
Properties = new Dictionary<string, PropertyWrapper<Limb>>
{
{"Head", new PropertyWrapper<Limb>( () => Head, v => Head = v ) },
{"LeftArm", new PropertyWrapper<Limb>( () => LeftArm, v => LeftArm = v ) },
{"RightArm", new PropertyWrapper<Limb>( () => RightArm, v => RightArm = v ) },
{"CenterTorso",new PropertyWrapper<Limb>( () => CenterTorso, v => CenterTorso = v )},
{"RightTorso", new PropertyWrapper<Limb>( () => RightTorso, v => RightTorso = v ) },
{"LeftTorso", new PropertyWrapper<Limb>( () => LeftTorso, v => LeftTorso = v ) },
{"RightLeg", new PropertyWrapper<Limb>( () => RightLeg, v => RightLeg = v ) },
{"LeftLeg", new PropertyWrapper<Limb>( () => LeftLeg, v => LeftLeg = v ) }
};
foreach (var property in Properties.Values) property.Value = new Limb();
}
public Limb this[string name]
{
get
{
return Properties[name].Value;
}
set
{
Properties[name].Value = value;
}
}
}
Yes, there is a bit of setup there, but it's all in one place, and it only executes once, when you instantiate the MechDef. Now you can access all of the limbs by string:
foreach (var pair in settings.LimbRepair)
{
if (pair.Value != false) continue;
var limb = mechDef[pair.Key];
limb.CurrentInternalStructure = Math.Max
(
1.0F,
limb.CurrentInternalStructure * (float)rng.NextDouble()
);
}
Link to DotNetFiddle example
You can create a DynamicObject to create your own dynamic Dictionary, See the explanation here
Assume that you want to provide alternative syntax for accessing
values in a dictionary, so that instead of writing
sampleDictionary["Text"] = "Sample text", you can write
sampleDictionary.Text = "Sample text".
This is the example from the same MSDN article above:
public class DynamicDictionary : DynamicObject
{
// The inner dictionary
Dictionary<string, object> dictionary = new Dictionary<string, object>();
public int Count
{
get { return dictionary.Count; }
}
// If you try to get a value of a property not defined
// in the class, this method is called.
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
// Converting the property name to lowercase so
// that property names become case-insensitive.
string name = binder.Name.ToLower();
// If the property name is found in a dictionary, set the result parameter
// to the property value and return true. Otherwise, return false.
return dictionary.TryGetValue(name, out result);
}
// If you try to set a value of a property that is not
// defined in the class, this method is called.
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// Converting the property name to lowercase so that
// property names become case-insensitive.
dictionary[binder.Name.ToLower()] = value;
// You can always add a value to a dictionary, so this method always returns true.
return true;
}
}
And this is how you can use your DynamicDictionary:
dynamic person = new DynamicDictionary();
// Adding new dynamic properties. The TrySetMember method is called.
person.FirstName = "Ellen";
person.LastName = "Adams";
Reflection is one way to get at it. https://stackoverflow.com/a/1954663/83250 actually answers this perfectly. I would however restructure your data so the mechDef object is another dictionary but if you must keep it like your question asks, this will work:
void Main()
{
Dictionary<string, bool> limbRepair = new Dictionary<string, bool>
{
{ "Head", false },
{ "LeftArm", false },
{ "RightArm", false },
// Etc.
};
MechDefinition mechDef = new MechDefinition();
List<Limb> limbs = new List<Limb>();
foreach (KeyValuePair<string, bool> limbsToRepair in limbRepair.Where(x => !x.Value))
{
Limb limb = mechDef.GetPropValue<Limb>(limbsToRepair.Key);
limb.CurrentInternalStructure = 9001;
}
}
public class MechDefinition
{
public MechDefinition()
{
Head = new Limb
{
Id = Guid.NewGuid(),
DateAdded = DateTime.Parse("2018-01-01"),
Name = "Main Head",
CurrentInternalStructure = 8675309
};
}
public Guid Id { get; set; }
public string Name { get; set; }
public int CurrentInternalStructure { get; set; }
public Limb Head { get; set; } = new Limb();
public Limb LeftArm { get; set; } = new Limb();
public Limb RightArm { get; set; } = new Limb();
// etc...
}
public class Limb
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime DateAdded { get; set; }
public int CurrentInternalStructure { get; set; }
public bool IsDisabled { get; set; }
}
public static class ReflectionHelpers
{
public static object GetPropValue(this object obj, string name)
{
foreach (string part in name.Split('.'))
{
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
public static T GetPropValue<T>(this object obj, string name)
{
object retval = GetPropValue(obj, name);
if (retval == null) { return default(T); }
// throws InvalidCastException if types are incompatible
return (T)retval;
}
}
Be aware that reflection is a very costly operation. If you are dealing with large sets of data, it will be very inefficient. Take a look at https://stackoverflow.com/a/7478557/83250 for a performance overview.
Also code-wise, I prefer to stay away from dynamic and reflection altogether. Reflection has its perks when you need to access a property attribute and dynamic is great if you don't have a strongly typed object. With that said, C# is a strongly typed language and should be treated as such whenever possible. By restructuring your mechDef as a Dictionary<string, Limb> object or something similar you will have a more efficient application.
If I understand correctly, You have something like this:
class LocationLoadoutDef
{
public LocationLoadoutDef()
{
Head = new Prop();
LeftArm = new Prop();
RightArm = new Prop();
CenterTorso = new Prop();
LeftTorso = new Prop();
RightTorso = new Prop();
LeftLeg = new Prop();
RightLeg = new Prop();
}
public Prop Head { get; set; }
public Prop LeftArm { get; set; }
public Prop RightArm { get; set; }
public Prop CenterTorso { get; set; }
public Prop LeftTorso { get; set; }
public Prop RightTorso { get; set; }
public Prop LeftLeg { get; set; }
public Prop RightLeg { get; set; }
...
}
class Prop
{
public float CurrentInternalStructure { get; set; }
...
}
So you can use reflection getting the type of the object and the property.
This is an example based on your pseudocode:
// your instance of LocationLoadoutDef
var mechDef = new LocationLoadoutDef();
//For reflection you need obtain the type
Type mechType = mechDef.GetType();
// loop your Dictionary
foreach (string limb in LimbRepair.Keys)
{
// If the property is false in the dictionary and the type has a property with that name
if (!LimbRepair[limb] && mechType.GetProperties().Any(p => p.Name == limb))
{
// Obtain the instance of the property
var property = mechType.GetProperty(limb).GetValue(mechDef) ;
// Get the property type
Type propertyType = property.GetType();
// If the property has a property CurrentInternalStructure
if (propertyType.GetProperties().Any(p => p.Name == "CurrentInternalStructure"))
{
// Obtain the current value for CurrentInternalStructure
var currentValue = propertyType.GetProperty("CurrentInternalStructure").GetValue(property);
// calculate the new value (I don't know what is rng)
var newValue = 1f ; //Math.Max(1f, (float)currentValue * (float)rng.NextDouble());
// set de value in the property
propertyType.GetProperty("CurrentInternalStructure").SetValue(property, newValue);
}
}
}
You can always create classic and working if .. else or switch.
Or create dictionary with function to update correct property
public class Repair
{
public bool Active { get; set; }
public Action<MechDef> Update { get; set; }
}
public class Settings
{
public readonly Dictionary<string, Repair> LimbRepair =
new Dictionary<string, bool> {
{
"Head",
new Repair { Active = false, mechDef => mechDef.Head.CurrentInternalStructure = yourFunctionForHead }
},
{
"LeftArm",
new Repair { Active = false, mechDef => mechDef.LeftArm.CurrentInternalStructure = yourFunctionForLeftArm }
},
// ... and so on
};
}
Then in the loop you will call correct update action, become much cleaner to use settings class with benefits of strong types and compiler help which prevent dynamic runtime errors
var updates = settings.LimbRepair.Where(pair => pair.Value.Active == false)
.Select(pair => pair.Value);
foreach (var repair in updates)
{
repair.Update();
}

How can I set my class properties values Using Reflection

Good Day,
Lets say this is my class:
public class MyClass {
public bool boolProp { get; set; }
public string stringProp { get; set; }
}
this is my IDictionary:
IDictionary<string, string> myDict=
new IDictionary<string, string>();
myDict.Add("boolProp", "true");
myDict.Add("stringProp", "teststring");
So I want to update my class properties using Reflection where my dictionary keys matches the name of property then set its value by creating a method, how is that?
Method parameter should be like this:
public void UpdateProperties(IDictionary<string, string> myDict) {
Thanks
With GetProperty method:
IDictionary<string, string> myDict = new Dictionary<string, string>();
myDict.Add("boolProp", "true");
myDict.Add("stringProp", "teststring");
var s = new MyClass();
var t = s.GetType();
foreach (var values in myDict)
{
var p = t.GetProperty(values.Key, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
var c = TypeDescriptor.GetConverter(p.PropertyType);
var convertedValue = c.ConvertFromInvariantString(values.Value);
p.SetValue(s, convertedValue);
}

Using custom object as dictionary key but get values by object property

I have a class:
public class Foo
{
public string Name { get; set; }
public double Value { get; set; }
public override string ToString()
{
return Name;
}
}
And I need to create a dictionary where key is object of Foo. Like this:
Foo foo1 = new Foo { Name = "Foo1", Value = 2.2 };
Foo foo2 = new Foo { Name = "Foo2", Value = 3.6 };
Dictionary<Foo, int> dic = new Dictionary<Foo, int>();
dic.Add(foo1, 1234);
dic.Add(foo2, 2345);
And now I want to get values from dictionary by passing Foo.Name property as key. Like this:
int i=dic["Foo1"];
// i==1234
i = dic["Foo2"];
// i==2345
Is it possible? Or the only way to pass object of Foo as key and override Equals method?
If you use a Foo as a key, you will need to use a Foo to index the dictionary as well.
Provided that what you actually need is most likely a Dictionary<string, int>, you could try overriding GetHashCode and Equals so that you can compare Foo objects based on the name only:
using System.Collections.Generic;
public class Foo {
public string Name { get; set; }
public double Value { get; set; }
public override string ToString() {
return Name;
}
public override int GetHashCode() {
return Name.GetHashCode();
}
public override bool Equals(object obj) {
Foo other = obj as Foo;
if (other == null) {
return false;
}
return Name.Equals(other.Name);
}
}
class Program {
static void Main(string[] args) {
Foo foo1 = new Foo { Name = "Foo1", Value = 2.2 };
Foo foo2 = new Foo { Name = "Foo2", Value = 3.6 };
Dictionary<Foo, int> dic = new Dictionary<Foo, int>();
dic.Add(foo1, 1234);
dic.Add(foo2, 2345);
int i = dic[new Foo { Name = "Foo1" }];
}
}
How about this:
class Program
{
public class Foo
{
public string Name { get; set; }
public double Value { get; set; }
public override string ToString()
{
return Name;
}
}
static void Main(string[] args)
{
Foo foo1 = new Foo { Name = "Foo1", Value = 2.2 };
Foo foo2 = new Foo { Name = "Foo2", Value = 3.6 };
var dic = new Dictionary<string, KeyValuePair<Foo, int>>();
dic.Add(foo1.Name, new KeyValuePair<Foo, int>(foo1, 1234));
dic.Add(foo2.Name, new KeyValuePair<Foo, int>(foo2, 2345));
int x = dic["Foo1"].Value;
var y = dic["Foo2"].Value;
Console.WriteLine(x);
Console.WriteLine(y);
Console.ReadKey();
}
}
Result will be:
1234
2345
The Dictionary is based on a hash table, that means it uses a hash lookup, which is a rather efficient algorithm to look up things. I suggest you think on your design and just use Dictionary<string,int>if you just want to use string as key
As a work around( not preferred way use only if you can't change your design), you could do this.
var key = dic.Keys.FirstOrDefault(c=>c.Name == "Foo1");
if(key != null)
dic[key]; //
Ok. I solved it by creating a class inherits Dictionary and overriding get value method. This solves my problem but I'm not sure about productivity with large collections.
public class MyDictionary:Dictionary<Foo, int>
{
public Bar():base()
{
}
new public int this[string key]
{
get
{
return this[base.Keys.Single(a => a.Name == key)];
}
}
}
And then this code works well:
MyDictionary<Foo, int> dic = new MyDictionary<Foo, int>();
dic.Add(foo1, 1234);
dic.Add(foo2, 2345);
int i=dic["Foo1"];

Categories