C# Get Values from object sender

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?
LVL 2
CipherISAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics TeacherCommented:
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 DeveloperCommented:
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

CipherISAuthor Commented:
No error with the casting but the nothing showing  up with intellisense and seem not to be getting any thing.
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

Russ SuterSenior Software DeveloperCommented:
If you cast like I did above you should get Intellisense. Make sure you use the parentheses.
CipherISAuthor 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 DeveloperCommented:
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.
CipherISAuthor Commented:
Found the value.  Receiving the below error.
Object2.jpg
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
@Russ Suter

That approach isn't any safer than a direct cast.
CipherISAuthor 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 DeveloperCommented:
@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.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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 DeveloperCommented:
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.
CipherISAuthor 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.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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.
CipherISAuthor Commented:
Ok, so how do I get the values?
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
You want the same "values" that you see in the Watch (i.e. the object/control's properties)?
CipherISAuthor Commented:
I'm trying to get to those values.  When I type s.  intellisense gives me below.
object4.jpg
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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.
CipherISAuthor Commented:
It's not going inside for loop.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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.
CipherISAuthor Commented:
Yes, that is what I want but it is not going inside the loop.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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

CipherISAuthor Commented:
Still not dropping inside for loop.
CipherISAuthor 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

kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
Unsure. It's working fine for me:

Screenshot
Note: I did change the logic a small bit to avoid issues with null values.
CipherISAuthor Commented:
ReflectedType: '((System.RuntimeType)(s.GetType())).ReflectedType' threw an exception of type 'System.NotSupportedException'
CipherISAuthor 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?
it_saigeDeveloperCommented:
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-
it_saigeDeveloperCommented:
Also, heed kaufmeds advice on null checking your values (I did not above).

-saige-
CipherISAuthor 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
it_saigeDeveloperCommented:
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-
CipherISAuthor 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.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
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-
CipherISAuthor 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)}
it_saigeDeveloperCommented:
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-
CipherISAuthor Commented:
Thanks.  That helped a lot.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."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.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.