C# Get Values from object sender

CipherIS
CipherIS used Ask the Experts™
on
I am trying to obtain the values from "sender"

object
I attempted to use linq

var x = from temp in sender select temp

Open in new window


but I receive error "Could not find an implementation of the query pattern"

How can I obtain the values in sender?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Cast "sender" to the correct type...for example:
xyz tmp = (xyz)sender; // where "xyz" is the correct TYPE that sender is (maybe "CameraMessageMonitor"?)
// now do something with "tmp"
Console.WriteLine(tmp.SomeValue.ToString());

Open in new window

Russ SuterSenior Software Developer

Commented:
Or you can use safe casting
(sender as Aimetis.Symphony.SDK.NotificationMonitors.CameraMessageMonitor).value

Open in new window

where "value" is the name of the property you're trying to access.

Normally you should do NULL checking after casting like this but in the case where you're casting a sender object you're pretty much guaranteed that the sender is an object and it is of the type you expect. If it isn't someone up the line made a pretty major programming mistake.

You can also significantly shorten the above line by including a using statement to import the namespace. It'll probably be something like this:
using Aimetis.Symphony.SDK.NotificationMonitors;

Open in new window

Then your cast is simply
(sender as CameraMessageMonitor).value

Open in new window

Author

Commented:
No error with the casting but the nothing showing  up with intellisense and seem not to be getting any thing.
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Russ SuterSenior Software Developer

Commented:
If you cast like I did above you should get Intellisense. Make sure you use the parentheses.

Author

Commented:
(sender as Aimetis.Symphony.SDK.NotificationMonitors.CameraMessageMonitor).value

Receive error - CameraMessageMonitor does not contain a definition 'value' and no extension method 'value' accepting first argument of type CameraMessageMonitor could be found.
Russ SuterSenior Software Developer

Commented:
As I said above, replace "value" with whatever property you want to access. You should get intellisense after you type the last dot "." following the close parenthesis.

Author

Commented:
Found the value.  Receiving the below error.
Object2.jpg
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
@Russ Suter

That approach isn't any safer than a direct cast.

Author

Commented:
var s = (CameraMessageMonitor)sender;

Open in new window


Above code worked.  I'm looking at my watch window and it is returning the below values.  How do I get the values of m_source and also AlarmDataTable and the sub values in there?

Thanks
Object3.jpg
Russ SuterSenior Software Developer

Commented:
@käµfm³d 👽

Safe cast will return a null value if the cast is invalid. You'll get an exception the other way. Which means it is safer. Exceptions are something to be avoided whenever possible.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
Calling .Vaue at the end of the cast as you have written it will most certainly result in a NullReferenceException if the cast fails, hence my comment. If you were to instead do the check for null, as you mentioned in comment, then it would be safer.
Russ SuterSenior Software Developer

Commented:
This is a technique I use frequently when working inside event handlers. The only two ways that cast could result in an exception are if I cast to the wrong type or the person who wrote the underlying code wrote the event handler wrong. Either way, an exception means bad code. Checking for null when casting the sender argument inside an event handler is unnecessary and wasteful code.

Author

Commented:
Ok, below code returned the values from the sender object.

var s = (CameraMessageMonitor)sender;

Open in new window


I included an image above "object3" which shows what is stored.

I am trying to get the values in "s".

I tried

var x = (from temp in s select new {}).ToList();

Open in new window


But the error I receive is "Could not find an implementation of the query pattern for source type 'CameraMessageMonitor'.  'Select' not found."

When I add "s" to my watch it provides all the values.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
You cannot LINQ against a control**...that doesn't make sense. You LINQ over a collection (i.e. something that implements IEnumerable).


** Unless, of course, some control happens to implement IEnumerable, which is technically possible.

Author

Commented:
Ok, so how do I get the values?
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
You want the same "values" that you see in the Watch (i.e. the object/control's properties)?

Author

Commented:
I'm trying to get to those values.  When I type s.  intellisense gives me below.
object4.jpg
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
You would need Reflection, then.

e.g.

foreach (System.Reflection.PropertyInfo property in sender.GetType().GetProperties(System.Reflection.BindingFlags.Instance))
{
    string name = property.Name;
    object value = property.GetValue(sender);

    Console.WriteLine("{0} - {1}", name, value.ToString());
}

Open in new window


This is a crude example. You'll probably have to tweak it.

Author

Commented:
It's not going inside for loop.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
The foreach loop in the above wraps the Reflection logic. Maybe I'm misunderstanding what you're trying to do, but based on what I read above you want the value of each property in the object--dynamically--and if so, then you use Reflection. My foreach loop just iterates over the object's properties.

Author

Commented:
Yes, that is what I want but it is not going inside the loop.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
Ah, my mistake. I think it needs another BindingFlag:

foreach (System.Reflection.PropertyInfo property in sender.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public))

Open in new window

Author

Commented:
Still not dropping inside for loop.

Author

Commented:
I tried this and it is still not going inside the for loop.
 foreach (PropertyInfo property in sender.GetType().GetProperties(BindingFlags.CreateInstance |
                                                                             BindingFlags.DeclaredOnly | 
                                                                             BindingFlags.Default |
                                                                             BindingFlags.ExactBinding |
                                                                             BindingFlags.FlattenHierarchy |
                                                                             BindingFlags.GetField | 
                                                                             BindingFlags.GetProperty |
                                                                             BindingFlags.IgnoreCase |
                                                                             BindingFlags.IgnoreReturn |
                                                                             BindingFlags.Instance |
                                                                             BindingFlags.InvokeMethod |
                                                                             BindingFlags.NonPublic |
                                                                             BindingFlags.OptionalParamBinding |
                                                                             BindingFlags.Public |
                                                                             BindingFlags.PutDispProperty |
                                                                             BindingFlags.PutRefDispProperty |
                                                                             BindingFlags.SetField |
                                                                             BindingFlags.Static |
                                                                             BindingFlags.SuppressChangeType
                                                                             ))
            {
                string name = property.Name;
                object value = property.GetValue(sender);

                Console.WriteLine("{0} - {1}", name, value.ToString());
            }

Open in new window

ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
Unsure. It's working fine for me:

Screenshot
Note: I did change the logic a small bit to avoid issues with null values.

Author

Commented:
ReflectedType: '((System.RuntimeType)(s.GetType())).ReflectedType' threw an exception of type 'System.NotSupportedException'

Author

Commented:
I put the code for the button and it works for the button but not for the CameraMessageMonitor.  Any other way to get the values?

Commented:
What property are you wanting to get?  The binding flags by default provide instance and public properties.  If you want the private and/or protected properties you will have to add BindingFlags.NonPublic; e.g. -
using System;
using System.Linq;
using System.Reflection;

namespace EE_Q28924773
{
	class Program
	{
		static void Main(string[] args)
		{
			SomeClass _someClass = new SomeClass();

			var _noFlags = (from prop in _someClass.GetType().GetProperties() select new { Name = prop.Name, Value = prop.GetValue(_someClass, null) });
			var _public = (from prop in _someClass.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) select new { Name = prop.Name, Value = prop.GetValue(_someClass, null) });
			var _nonPublic = (from prop in _someClass.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic) select new { Name = prop.Name, Value = prop.GetValue(_someClass, null) });

			Console.WriteLine("NoFlag Properties");
			foreach (var item in _noFlags)
				Console.WriteLine(item);

			Console.WriteLine();
			Console.WriteLine("Public Properties");
			foreach (var item in _public)
				Console.WriteLine(item);

			Console.WriteLine();
			Console.WriteLine("NonPublic Properties");
			foreach (var item in _nonPublic)
				Console.WriteLine(item);

			Console.ReadLine();
		}
	}

	class SomeClass
	{
		string _privateStringField = "Private Field";
		protected internal string _protectedInternalStringField = "Protected Internal Field";
		internal string _internalStringField = "Internal Field";
		protected string _protectedStringField = "Protected Field";
		public string _publicStringField = "Public Field";

		string PrivateStringProperty 
		{
			get { return _privateStringField; }
			set { _privateStringField = value; } 
		}

		protected internal string ProtectedInternalStringProperty
		{
			get { return _protectedInternalStringField; }
			set { _protectedInternalStringField = value; }
		}

		internal string InternalStringProperty
		{
			get { return _internalStringField; }
			set { _internalStringField = value; }
		}

		protected string ProtectedStringProperty
		{
			get { return _protectedStringField; }
			set { _protectedStringField = value; }
		}

		public string PublicStringProperty
		{
			get { return _publicStringField; }
			set { _publicStringField = value; }
		}
	}
}

Open in new window

Which produces the following output -Capture.JPGYou can combine binding flags as well since it is a flag based enumeration; e.g. -
using System;
using System.Linq;
using System.Reflection;

namespace EE_Q28924773
{
	class Program
	{
		static void Main(string[] args)
		{
			SomeClass _someClass = new SomeClass();

			var _allProperties = (from prop in _someClass.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) select new { Name = prop.Name, Value = prop.GetValue(_someClass, null) });

			Console.WriteLine("All Properties");
			foreach (var item in _allProperties)
				Console.WriteLine(item);

			Console.ReadLine();
		}
	}

	class SomeClass
	{
		string _privateStringField = "Private Field";
		protected internal string _protectedInternalStringField = "Protected Internal Field";
		internal string _internalStringField = "Internal Field";
		protected string _protectedStringField = "Protected Field";
		public string _publicStringField = "Public Field";

		string PrivateStringProperty 
		{
			get { return _privateStringField; }
			set { _privateStringField = value; } 
		}

		protected internal string ProtectedInternalStringProperty
		{
			get { return _protectedInternalStringField; }
			set { _protectedInternalStringField = value; }
		}

		internal string InternalStringProperty
		{
			get { return _internalStringField; }
			set { _internalStringField = value; }
		}

		protected string ProtectedStringProperty
		{
			get { return _protectedStringField; }
			set { _protectedStringField = value; }
		}

		public string PublicStringProperty
		{
			get { return _publicStringField; }
			set { _publicStringField = value; }
		}
	}
}

Open in new window

Which produces the following output -Capture.JPGIf you want fields (because not all fields have properties) then use the GetFields methods with the appropriate binding flags; e.g. -
using System;
using System.Linq;
using System.Reflection;

namespace EE_Q28924773
{
	class Program
	{
		static void Main(string[] args)
		{
			SomeClass _someClass = new SomeClass();

			var _allProperties = (from prop in _someClass.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) select new { Name = prop.Name, Value = prop.GetValue(_someClass, null) });
			var _allFields = (from field in _someClass.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) select new { Name = field.Name, Value = field.GetValue(_someClass) });

			Console.WriteLine("All Properties");
			foreach (var item in _allProperties)
				Console.WriteLine(item);

			Console.WriteLine();
			Console.WriteLine("All Fields");
			foreach (var item in _allFields)
				Console.WriteLine(item);

			Console.ReadLine();
		}
	}

	class SomeClass
	{
		string _privateStringField = "Private Field";
		protected internal string _protectedInternalStringField = "Protected Internal Field";
		internal string _internalStringField = "Internal Field";
		protected string _protectedStringField = "Protected Field";
		public string _publicStringField = "Public Field";

		string PrivateStringProperty { get; set; }
		protected internal string ProtectedInternalStringProperty { get; set; }
		internal string InternalStringProperty { get; set; }
		protected string ProtectedStringProperty { get; set; }
		public string PublicStringProperty { get; set; }
	}
}

Open in new window

Which produces the following output -Capture.JPG-saige-

Commented:
Also, heed kaufmeds advice on null checking your values (I did not above).

-saige-

Author

Commented:
Yes, and like I said, the code works for the button.  I tried it but it is not working for
var s = (CameraMessageMonitor)sender;

foreach (PropertyInfo property in s.GetType().GetProperties(BindingFlags.Instance |
                                                                        BindingFlags.Public 
                                                                        ))
{
    string name = property.Name;
    object value = (property.GetValue(sender) ?? null).ToString();

    Console.WriteLine("{0} - {1}", name, value.ToString());
}

Open in new window


The code is NOT going inside the "for loop".

I am trying to get the values in the the attached image
Object3.jpg

Commented:
In your image.  m_source is a field, not a property.  In order to retrieve this, you need to use the GetField or GetFields method.  Also, m_source is a protected field, which means that you need to include BindingFlags.NonPublic in your list of BindingFlags parameters.

From there, you can then get the properties (the wrench indicates properties) of m_source by retrieving it's type and using GetProperties.

-saige-

Author

Commented:
I tried below

            foreach (PropertyInfo property in s.GetType().GetProperties(BindingFlags.CreateInstance |
                                                                                         BindingFlags.DeclaredOnly |
                                                                                         BindingFlags.Default |
                                                                                         BindingFlags.ExactBinding |
                                                                                         BindingFlags.FlattenHierarchy |
                                                                                         BindingFlags.GetField |
                                                                                         BindingFlags.GetProperty |
                                                                                         BindingFlags.IgnoreCase |
                                                                                         BindingFlags.IgnoreReturn |
                                                                                         BindingFlags.Instance |
                                                                                         BindingFlags.InvokeMethod |
                                                                                         BindingFlags.NonPublic |
                                                                                         BindingFlags.OptionalParamBinding |
                                                                                         BindingFlags.Public |
                                                                                         BindingFlags.PutDispProperty |
                                                                                         BindingFlags.PutRefDispProperty |
                                                                                         BindingFlags.SetField |
                                                                                         BindingFlags.Static |
                                                                                         BindingFlags.SuppressChangeType
                                                                                         ))

I added one at a time to see if it would drop inside the for loop and it still did not drop in the for loop.
Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015
Commented:
That "m_source" looks like a private field. You'd have to modify the Reflection a bit in order to get to that. However, since it's a private field, that really means that it's an implementation detail, and you really shouldn't be coding against implementation details.

Warning out of the way, you'd modify the Reflection as:

var s = (CameraMessageMonitor)sender;
FieldInfo m_source_field = sender.GetType().GetField("m_source", BindingFlags.Instance | BindingFlags.NonPublic);

if (m_source_field != null)
{
  object m_source = m_source_field.GetValue(s);
  
  foreach (PropertyInfo property in m_source.FieldType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
  {
      string name = property.Name;
      object value = (property.GetValue(sender) ?? null).ToString();

      Console.WriteLine("{0} - {1}", name, value.ToString());
  }
}

Open in new window




But before you go down that road, if you put a breakpoint on one of these lines, what do you get if you run the following within the Immediate Window?

?sender.GetType().GetField("m_source", BindingFlags.Instance | BindingFlags.Public)

Commented:
GetProperties will only return properties, not fields (you will get the field values from their associated properties if the property defines a get method).  If you need the fields, you must use GetFields with the appropriate binding flags.  In 99.9% of all cases the following binding flags parameters will suffice:
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static

Open in new window

-saige-

Author

Commented:
I'm walking through it.  I am getting the property.name.  When I get the value I receive the below error.

'(property.GetValue(s) ?? null).ToString()' threw an exception of type 'System.Reflection.TargetException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146232829
    HelpLink: null
    InnerException: null
    Message: "Object does not match target type."
    Source: "mscorlib"
    StackTrace: "   at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)\r\n   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\r\n   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\r\n   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)\r\n   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)\r\n   at System.Reflection.PropertyInfo.GetValue(Object obj)"
    TargetSite: {Void CheckConsistency(System.Object)}
Commented:
That is because the object that represents m_source is not a string, you need to cast it as it's type or just return the object and use reflection to get the object's type and associated properties.  This is the same that that was suggested by Kaufmed above: http:/Q_28924773.html#a41456928

Except that I did notice an error in the implementation.  You probably want to do this:
var s = (CameraMessageMonitor)sender;
FieldInfo m_source_field = sender.GetType().GetField("m_source", BindingFlags.Instance | BindingFlags.NonPublic);

if (m_source_field != null)
{
  object m_source = m_source_field.GetValue(s);
  
  foreach (PropertyInfo property in m_source.FieldType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
  {
      string name = property.Name;
      // Get the property value from m_source not sender since we are looking at the m_source properties
      object value = (property.GetValue(m_source) ?? null).ToString();

      Console.WriteLine("{0} - {1}", name, value.ToString());
  }
}

Open in new window

-saige-

Author

Commented:
Thanks.  That helped a lot.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
Line 12 in both offerings should be (the string "null", not the operator):

object value = (property.GetValue(m_source) ?? "null").ToString();

Open in new window


@it_saige

Good catch. I was hand-coding that one in TextPad, so I didn't catch that bit.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial