I have found this example to set the value of a Class property:
Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
But I want to set value of a variable in my "this".
i.e. in my main form I have a private double "Momentum"
string value = "5.5";
var property = this.GetType().GetProperty("Momentum");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
This does NOT work - "property" is null.
How do I alter the above code to achieve this?
Seriously, why are you using reflection if you need to set the field value from a variable you own?
Okay, let's forget that... If you have a field and not a property, you need to use GetField:
var value = "5.5";
var field = this.GetType().GetField(nameof(Momentum), BindingFlags.NonPublic);
field.SetValue(self /* or this */, value);
Also, this might be a good place to use nameof, but that is just a suggestion.
Related
In C# I have multiple instantiations of a class "CItems"(see below). I retrieve a string at run-time of the instantiation I want to use(in this case to call a public method-"addPropertyToList"). I know I have to use reflection but I can't seem to get it right.
CItems me = new CItems();
CItems conversations = new CItems();
string whichCItem = "me"
properties = <whichCItem>.addPropertyToList(properties, "FirstName", "Ken");
I tried many things like:
var myobject = this;
string propertyname = "me";
PropertyInfo property = myobject.GetType().GetProperty(propertyname);
object value = property.GetValue(myobject, null);
But that resulted in:
Object reference not set to an instance of an object. Because property ends up null.
Thanks for any help and please be gentle. I really have no idea what I am doing and I may have used some wrong terminology.
A simple Dictionary<T, U> might work for you.
Consider an example:
CItems me = new CItems();
CItems conversations = new CItems();
...
var dic = new Dictionary<string, CITems>();
doc.Add("me", me);
doc.Add("conversations", conversations);
...
//find object
CITems result= null;
dic.TryGetValue(searchString, out result);
PropertyInfo property = myobject.GetType().GetProperty(propertyname);
This is the correct approach for tretrieving the property identified by propertyname. You already know the type it is declared on, so you just use
var propertyInfo = CItems.GetProperty(propertyname)
to retrieve the class property. What you now need to do is set that property on the identified instance, so that you can call
propertyInfo.SetValue(<instance>, value);
How are your instances identified? Surely you are not giving back the name of the variable in which the object pointer is stored?
Is something like the following achievable?
IEnumerable<CItems> myItems = new { new CItem("me"), new CItem("conversations") }
void somemethod(string instanceName, string propertyname)
{
var instance = myItems.FirstOrDefault(item => item.Name == instanceName);
if(instance == null) return;
var propertyInfo = CItems.GetProperty(propertyname);
propertyInfo.SetValue(instance, value);
}
This is the statement I used to set the value :
this.codeactivity.output.Value1
I am trying to change the numeric value alone to work dynamically.
string sValue = "1";
this.codeactivity.output.value+ svalue = "Worked";
I have given one more try as below.
PropertyInfo[] myPropertyInfo;
myPropertyInfo = this.CodeActivity.GetType().GetProperties();
this.CodeActivity.Output.
for (int i = 0; i < myPropertyInfo.Length; i++)
{
Console.WriteLine(myPropertyInfo[i].ToString());
}
Please help me with this. Thanks
**Question what i raised, here go the answer **
Statement One: this.codeactivity.output.Value1 here i am tried to change variable name(Value1) dynamically.
This is how i tried to change the value: Eval("this.codeactivity.output."&Value1&") it will work if i do it in VbScript. But here i am working with object oriented programming C#. Based on the comments to the question i started with C# Reflection concept, then i landed with the solution.
**Solution: **
string propertyValue = "Mohan"
string propertyName = "Value1"
Type type = this.codeactivity.output.GetType();
PropertyInfo propertyInfo = type.GetProperty(propertyName)//Get particular Property;
Type propertyType = propertyInfo.PropertyType; //get the property type
object propertyVal = Convert.ChangeType(propertyValue , propertyType);//based on type change value.
propertyInfo.SetValue(this.codeactivity.output, propertyVal, null);//Set the value of the property
Thanks
I have this below script in my Class.
aggrgt.Add(new PlainBrgDataSummaryChartAggrgt
{
label = m.label,
goal = m.goal,
groupCode = m.groupCode,
groupValue1 = m.groupValue1,
graphSwitch = m.graphSwitch,
orderByAsc = m.orderByAsc,
metricID = m.metricID,
scoreWk1 = metricscoreWk1.metricScore1,
});
The condition I want is when metricscoreWk1 is null, scoreWk1 = metricscoreWk1.metricScore1 is eliminated.
This may help you:
scoreWk1 = metricscoreWk1.metricScore1 ==null ? 0 : metricscoreWk1.metricScore1
That is, if the value of metricscoreWk1.metricScore1 is null 0(or else any default value) will be assigned else the original value will be assigned to scoreWk1
You can't put "" for Double, the closest analogue, INHO, is Double.NaN (Not A Number):
// Let's have Double.NaN for unknown/undefined etc. value
scoreWk1 = metricscoreWk1.metricScore1 ?? Double.NaN;
You could either:
Create the PlainBrgDataSummaryChartAggrgt object without setting the scoreWk1 field. If metricscoreWk1 is not null, you then set the field and you then add the object to the list.
If you have a setter for metricScore1, you could add a check wherein you ensure that metricscoreWk1 is not null. If it is, the value is not updated.
The second option would allow you to keep your current initialization structure, but the first is more explicit. Should you opt for the second approach, I'd recommend you document it.
[ConfigurationProperty("Name", DefaultValue = "test")]
public string Name
{
get { return (string)this["Name"]; }
set { this["Name"] = "Ram"; }
}
CorticonConfig config = new CorticonConfig();
string test = config.Name;
I have a property with "Name" and also I am setting the value to name.While I m trying to get the value, I am getting default value.
My question is: can we set property value as above?
And what is the behaviour of Default value property?
Your property setter doesn't work like you think it's working.
The set part is executed when you set the property (you make property = something), and in that case, your something would be on the value keyword.
So in your case, if you do:
CorticonConfig config = new CorticonConfig();
config.Name = "whatever";
string test = config.Name;
test will have "Ram", because you are always asigning that value there, but it won't execute that code unless you do config.Name = <something>.
The correct way to have a setter like that would be:
set
{
this["Name"] = value;
}
And if you need a default value other than the one you are setting on your attribute, apply it after constructing the object:
CorticonConfig config = new CorticonConfig();
config.Name = "Ram";
The DefaultValue you pass on the attribute gives it a default value if no settings have been ever saved, so when you read it, it'll return that.
So I have a horribly designed class that I can't change that has properties like this:
object.Color1
object.Color2
object.Color3
etc...
How can I iterate through those with a for loop. In other words, something like this:
for (int i = 0; i <= 40; i++)
{
string PropertyName = "Color" + i;
if (object.PropertyName != "")
{
// do something
}
}
Obviously this code wouldn't work but it gives you an idea of what I'm after. I have to do some processing on each property and I don't want to repeat my code 40 times. :) A loop would be perfect, I'm just not sure how to create the name of the property on the fly.
EDIT: Ok so I've tried the following code:
for (int i = 1; i <= 20; i++ )
{
var type = pendingProduct.GetType();
var colorProperty = type.GetProperty("Color" + i);
string colorValue = colorProperty.GetValue(type, null).ToString();
var colorSkuProperty = type.GetProperty("Color" + i + "SKU");
string colorSkuValue = colorSkuProperty.GetValue(type, null).ToString();
if (String.IsNullOrEmpty(colorValue)) continue;
ProductColor color = new ProductColor {Color = colorValue, ProductSizes = productSizes};
if (!String.IsNullOrEmpty(colorSkuValue)) color.SKU = colorSkuValue;
}
I'm getting an error "Object does not match target type" on this line:
string colorValue = colorProperty.GetValue(type, null).ToString();
Am I doing something wrong here?
You're looking for reflection:
PropertyInfo property = typeof(SomeType).GetProperty("Color" + i);
string value = (string)property.GetValue(obj, null);
Note that this will be slow.
If you do it many times, you can make it faster by caching Delegate.CreateDelegate(..., property.GetGetMethod()) in an array.
You can use reflection for that:
var type = myObject.GetType();
var property = type.GetProperty("Color1");
var value = property.GetValue(myObject, null));
This is how i do to help finding.
$abc = array(
'a' => 'world',
'b' => 'good',
);
$object = (object) $abc;
foreach($object as $k)
{
var_dump($object);
}
You can use reflection to get the property by name. In your example you can use:
var pi = obj.GetType().GetProperty(PropertyName);
var val = pi.GetValue(obj,null);
In order to obtain the value of the property which name is PropertyName. You should check for pi != null because if a requested property does not exists null is returned.
If the function you are writing is time critical, you should anyway pay attention that reflection has some performance drawbacks.
Have a look at InvokeMethod...
MSDN
Example at codeproject
You could try something along the lines of...
Type type = this.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo p in properties)
{
// Check property is the one you want
// and carry out your code...
}
Also, If you have access to the code I.E. you can change the internals but want to leave the public API intact you could just add the information to a private collection when the object is constructed. The collection could then be exposed by a public property for you to iterate over. A bit hacky but an alternative to using reflection.