I want to supply unknown "object" and return the value of one of its members. Response is required in C#.
Generically I guess I'm looking for the code to this method
public static object GetObjectMemberValue (object myObject, string memberName)
More specifically I'm doing this for resource strings in Silverlight and need to write this method. It resides in a common project is used against a few different Resx dictionaries, thus I don't have access to the type information.
public static string GetString (object StringResources, string ResourceId)
Thank you!
This will get your value... Can you give me more info in the resx part of the question?
public static object GetObjectMemberValue(object myObject, string memberName)
{
PropertyInfo dateProperty = myObject.GetType().GetProperty(memberName);
return dateProperty.GetValue(myObject, null);
}
if you know the objects type, then cast to it?
Or it should at least implement an interface if you don't know the explicit type?
MyType value = (MyType)objectGetter() //this is the function that returns the unknown.
value.GetMember()
static class ObjectExtensions {
public static object GetObjectPropertyValue(this object o, string propertyName) {
return o.GetType().GetProperty(propertyName).GetValue(o, null);
}
}
class Test {
public string Message {get; set;}
}
class Program {
static void Main(string[] args) {
object t = new Test { Message = "Hello, World!" };
Console.WriteLine(t.GetObjectPropertyValue("Message").ToString());
}
}
First get the type of the object:
Type myObjectType = myObject.GetType();
Then, you can use the returned Type object to get the property's info, and then it's value.
o.GetType().InvokeMember( "MemberName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, o, null );
Related
I want to implement this method from MOQ. (Little out of my depth here)
ISetup<T> Setup(Expression<Action<T>> expression);
public class Foo {
public string Bar { get; set; }
public int Baz { get; set; }
}
public class MyCoolClass
{
public ? Evaluate<Expression<Action>>(expression);
//I want to be able to access and test the value of Foo.Bar (see below)
}
public class ClientOfMyClass
{
public void UseTheMethod()
{
MyCoolClass myCool = new MyCoolClass();
bool result = myCool.Evaluate<Foo>(f => f.Bar);
}
}
Basically, I am trying to write a method that will allow the caller to specify a property on an object with an expression, and allow me to test the value of that property and do something with it.
You want to use an Expression<Func<>> parameter, and check that it contains a Body, and a Member of type PropertyInfo, and use GetValue() passing your object in.
public static void Evaluate<TObj,TProp>(
this TObj obj,
Expression<Func<TObj, TProp>> expr)
{
var prop = (expr.Body as MemberExpression)?.Member as PropertyInfo;
var val = prop?.GetValue(obj);
if (val != null) {
//Do something
}
}
Note that the above code requires the passed in lambda to point to a Property. If you want to handle Fields as well as Methods, they will come in as different types of Expressions, and you'll want to handle handle them slightly differently. For more context and usage, here's a Fiddle.
Edit: Updated to work with other property types.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have been trying for a while to achieve this.
I have seem some similar answers but it didn't work for me.
I am not an expert in C# so be aware.
(I don't even know if this is possible to be achieved)
All enums are in the same class.
All numbers are unique.
My problem:
enum BAR
{
A = 0,
B = 1
{
enum FOO
{
C = 2,
D = 3
}
public static string GetEnumName(object o)
{
// Need help here
}
public static string GetName(object o)
{
// Need help here
}
Using Example:
GetEnumName(BAR.A); // result = BAR
GetName(BAR.A); // result = A
GetEnumName(FOO.C); // result = FOO
GetName(FOO.C); // result = C
You can use these methods (use Enum as parameter-type instead of Object):
public static string GetEnumName(Enum input)
{
return input.GetType().Name;
}
public static string GetName(Enum input)
{
return Enum.GetName(input.GetType(), input);
}
The GetName method is overkill as:
FOO.C.ToString();
Either that or you have a variable:
object o = FOO.C;
o.ToString();
Will get you "C" as a result.
For GetEnumName you can use:
FOO.C.GetType().Name;
or
object o = FOO.C;
o.GetType.Name;
Lastly, if your two methods are really intended to work only on enum values, the input value should not be object but rather Enum in order to enforce some level of type safety.
public static string GetName(Enum value)
public static string GetEnumName(Enum value)
Frankly, it's a little disappointing that you're spending time arguing in comments rather than just trying this stuff.
Below code should give you some idea....
static void Main(string[] args)
{
Console.WriteLine($"GetEnumName(FOO.D):{GetEnumName(FOO.D)}");
Console.WriteLine($"GetName(FOO.D):{GetName(FOO.D)}");
Console.Read();
}
public static string GetEnumName(object o)
{
// Need help here
Type t = o.GetType();
return t.Name;
}
public static string GetName(object o)
{
// Need help here
return o.ToString();
}
The static Enum class has a method to get the name of the constant value given the type of Enum and the value. See the relevant documentation here. However, for reference it's as simple as
Enum.GetName(typeof(Foo), value);
I use this when I don't know the type of Enum being used (e.g. when I'm using a generic).
To get the name of the Enum, you have to use a little reflection on the type.
typeof(value).toString()
public static string GetEnumName(object o)
{
if ( o is Enum)
return o.GetType().Name;
return null;
}
public static string GetName(object o)
{
if (o is Enum)
{
return Enum.GetName(o.GetType(), o);
}
return null;
}
I am trying to create a function that can return a field from its object.
Here is what I have so far.
public class Base
{
public string thing = "Thing";
public T GetAttribute<T>(string _name)
{
return (T)typeof(T).GetProperty(_name).GetValue(this, null);
}
}
What I would ideally like is to call:
string thingy = GetAttribute<string>("thing");
but I have a feeling I got the wrong end of the stick when reading up on this because I keep getting null reference exceptions.
First thing - thing is a field, not a property.
Another thing is that you have to change parameter type to get it working:
public class Base {
public string thing = "Thing";
public T GetAttribute<T> ( string _name ) {
return (T)typeof(Base).GetField( _name ).GetValue (this, null);
}
}
BTW - you can get property/field value by referencing an instance:
var instance = new Base();
var value = instance.thing;
thing is a field not a property. You should use GetField method instead of GetProperty.
Another problem is you are looking in typeof(T). You should look for the field in typeof(Base).
The whole function should be changed to
public T GetAttribute<T>(string _name)
{
return (T)GetType().GetField(_name).GetValue(this);
}
If you want to have an extension method to get field value of a type you can use this
public static class Ex
{
public static TFieldType GetFieldValue<TFieldType, TObjectType>(this TObjectType obj, string fieldName)
{
var fieldInfo = obj.GetType().GetField(fieldName,
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic);
return (TFieldType)fieldInfo.GetValue(obj);
}
}
Use it like
var b = new Base();
Console.WriteLine(b.GetFieldValue<string, Base>("thing"));
Using BindingFlags will help you to get field value even if it is private or static field.
SO Community,
So I'm learning C# and am still trying to wrap my head around reflection. In particular trying to use it to access a property of a property on a class.
I've boiled down the basic task that I'm trying to accomplish below:
public enum SIGNAL_STATE { NOT_RETRIEVED = 0, RETRIEVING = 1, RETRIEVED = 2, FAILED = 3 }
public class MyObjectClass
{
public string MyString;
private SIGNAL_STATE _state = SIGNAL_STATE.NOT_RETRIEVED;
public SIGNAL_STATE State { get { return _state; } set { _state = value;} }
}
public class NeedToReflect
{
private MyObjectClass _myObject1 = new MyObjectClass();
private MyObjectClass _myObject2 = new MyObjectClass();
private MyObjectClass _myObject3 = new MyObjectClass();
public MyObjectClass MyObject1
{
get{return _myObject1;}
set{_myObject1 = value;}
}
public MyObjectClass MyObject2
{
get{return _myObject2;}
set{_myObject2 = value;}
}
public MyObjectClass MyObject3
{
get{return _myObject3;}
set{_myObject3 = value;}
}
public static void Main(string [] args){
NeedToReflect needToReflect = new NeedToReflect();
string fieldName;
for(int idx = 1; idx<=3; ++idx)
{
fieldName = String.Format("MyObject{0}",idx);
//TODO: set state of 'MyObject' values to SIGNAL_STATE.RETRIEVING
}
}
}
edit 1:
At Yair Nevet's suggestion I'm grabbing the FieldInfo from the applicable object like,
FieldInfo fieldInfo = needToReflect.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
But from there I get hung up on accessing and setting the right 'State' Field/Property on that member field
Solution (ie. here's what I plugged in on that TODO comment):
// Determine what binding flags will give us proper access to our member field
BindingFlags bindFlags = BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance;
// Get the field for that field
FieldInfo fieldInfo = needToReflect.GetType().GetField(fieldName, bindFlags);
// Pass in the containing object that we're reflecting on to get an instance of the member field
MyObjectClass myField = (MyObjectClass) fieldInfo.GetValue(needToReflect);
// We can now directly access and edit the value in question
myField.State = SIGNAL_STATE.RETRIEVING;
That does it. Thanks to Shlomi Borovitz for pointing me in the right direction.
Thanks!
The FieldInfo object which returned by GetField has property which called FieldInfo, which returns the type of that field.
And you can query it for that type's (the type of the field) properties/fields (and whatever you want) - and get/set them.
Remember that both GetType method (of any object), and the FieldInfo.FieldType property return Type object, that you can query in reflection.
object obj =...
var field = obj.GetType().GetField(fieldName,...);
field.FieldType.GetField(...
//etc... etc...
For each field, you can query the type and for each type, you can query the fields, and get/set them.
BTW, in C# 4.0 you can use the dynamic pseudo type (it used as a type when declaring dynamic variable, but it's not a real type), and then using that variable, while assuming which properties/fields/methods that variable would have in runtime (ie, using them like they are known in compile time although they don't).
This will not work for private members (and I can't warn you enough against calling private members in reflection), but for public members, this would make your code simple and readable, like you never used reflection (although, behind the scenes [in this case] reflection would be used).
You are trying to access a Property while the member is actually a private Field:
propertyName = String.Format("MyObject{0}",idx);
Use GetField method instead for that:
needToReflect.GetType().GetField(propertyName, BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
Go through these steps...
1) Get the Type.
2) Have an instance of that type.
3) Get the PropertyInfo for the property.
4) Call "GetSetMethod" on the PropertyInfo object. It will return a MethodInfo object.
5) Invoke the MethodInfo object using the instance of the type and a value.
Given:
class ClassyMcClass
{
public int PropertyB { get; set; }
}
class MyClass
{
public ClassyMcClass PropertyA { get; set; }
}
The following code uses reflection on a MyClass object to set the int value of PropertyB in PropertyA to NewValue:
PropertyInfo propA = typeof(MyClass).GetProperty("PropertyA");
PropertyInfo probBofA = propA.PropertyType.GetProperty("PropertyB");
// Set property B of property A, where obj is of type MyClass
probBofA.SetValue(propA.GetValue(obj), NewValue, null);
I have a Variable class and and 3 subclasses: VariableBool, VariableLong and VariableDouble. Each subclass defines only a value member of the type of the suffix.
Now, I need to transfert objects based on these classes over WCF. I have multiple clients registering their variale to a server. Whenever a value changes on one client, it's updated in all other clients.
My question is: is there a way to do:
someVar.Value = anotherVar.Value;
regardless of the type, wihout having to check for type, e.g.:
VariableBool anotherVarBool = anotherVar as VariableBool;
if (anotherVarBool != null) {
(someVar as VariableBool).Value = anotherVar.Value;
}
// check other types...
What am I missing? Is there a patern of some kind? Could I use reflection?
Also, I don't think I can use Generics because of the WCF (I've tried but I could make it work).
Thanks
If you are using mex-generated WCF proxies, then I suspect reflection (or ComponentModel) is indeed the simplest option - something like:
public static void Copy<T>(T source, T destination,
string propertyName) {
PropertyInfo prop = typeof(T).GetProperty(propertyName);
prop.SetValue(destination, prop.GetValue(source, null), null);
}
Or if you want to use it even with the variable types as the base-class:
public static void Copy(object source, object destination,
string propertyName) {
PropertyInfo sourceProp = source.GetType().GetProperty(propertyName);
PropertyInfo destProp = destination.GetType().GetProperty(propertyName);
destProp.SetValue(destination, sourceProp.GetValue(source, null), null);
}
Why don't you to put the Value member in the base class Variable.
In that case,
public void UpdateValue( Variable variable )
{
if( variable != null )
// do something with variable.Value
}
However, if you really want to use inheritance, you need to tell the base class what are the sub types by using KnownType attribute and its method
[DataContract()]
[KnownType( "GetKnownType" )]
public class Variable
{
public object Value;
private static Type[] GetKnownType()
{
// properties
return new []{ typeof(VariableBool),
typeof(VariableLong),
typeof(VariableDouble),};
}
}
[DataContract()]
public class VariableBool : Variable
{
}
[DataContract()]
public class VariableLong : Variable
{
}
[DataContract()]
public class VariableDouble : Variable
{
}