How to access data in System.Object? - c#

I'm trying to learn how to access data in a System.Object. There's a Visual Studio 2015 c# .net application which calls a Matlab function using the following code:
object result = null;
matlab.Feval("matlabTest", 1, out result);
If I hover over the variable result when debugging it shows up as
result|{object[1]}. If I slide down to further expand result it shows up as [0]:{object[53,13]}. Then when sliding down further I can see the two dimensional array of strings and doubles. So, the debugger can see and display the valid data in "result" but I have no idea how to access the strings and doubles at runtime. Any suggestions would be appreciated.

Based on the information you provided, you need to do something like the following:
object[] first_array = (object[])result;
object[,] second_array = (object[,])first_array[0];
And then access the second array like this:
var item = second_array[5,5];
Another approach is to use the dynamic keyword like this:
dynamic dynamic_result = result;
var test_value = dynamic_result[0][5, 5];

You can always call <variable>.GetType() to see which type it is and then cast it based on this information.

an easy way to get access to object, is use typeof() to get it type, and use Reflection to access its data.

Related

How to declare an array of deserialized class parameters without initializing it?

I consider this as a continuation of what I've learned from my two previous threads. Instead of Javascript I will be using pure C#.
I have a class with 3 parameters in it, and I am creating a variable which is a result of deserialization to class type
var param = js.Deserialize<ClassName>(jqData.Params);
Based on what I've learned from my first thread, it stores values based on inputs I've made within 3 textboxes that I have.
For our purposes, let's assume I only placed input in a second textbox out of three, so the values would be null, "abc", null.
Now, I got some very good suggestions from my second post, which I want to implement.
I want to create an array of objects, WITHOUT initializing, since those objects already hold values, reduce array down to 1 element based on criteria from that excellent post, and then proceed with my validation logic.
However, I am struggling with declaring array part. From what I saw here in SO, most of threads are talking about declaring and initializing those elements. I don't need it.
What I need is to declare an array, which would have class elements in it, something like array = [param.elem1, param.elem2, param.elem3], and when I run a code, it will return [null, "abc", null].
Can you please point me in the right direction on how to properly declare such array?
Your idea was close to how this can be handled. Just change your array = [param.elem1, param.elem2, param.elem3] to:
var myArray = new object[] { param.elem1, param.elem2, param.elem3 };
If you know the type of param.elem1/2/3, you can use the specific type (e.g. string[] instead of object[]).

How do I set a function property on a dynamic COM object?

I am looking at Amibroker's OLE documentation examples in VBScript and JS trying to convert it to C# code:
http://www.amibroker.de/guide/objects.html
In it it says:
Filter( 0, "index" ) = 1; // include only indices
Filter( 1, "market" ) = 2; // exclude 2nd market
I have a C# dynamic object that I built, and I can find and call the Filter() function, but I have no idea how to set the value after the function call, since that is not valid C# syntax.
Here is the C# code:
var type = Type.GetTypeFromProgID("Broker.Application");
dynamic ab = Activator.CreateInstance(type);
ab.Analysis.Filter(0, "market") = 2; // This is obviously not compiling
When I call ab.Analysis.Filter(0, "market"), it simply returns an int for the current setting. Is the answer to use reflection somehow? I haven't tried to go down that route wondering if there is a simpler solution.
That code snippet you found is jscript, not VBScript. It is not a function property, it is an indexed property. VB.NET supports them well. But the C# team did not like them and only permits one indexed property for a class, the indexer (this[]). By popular demand they added support in version 4. Only for COM interop. Which is what you are using.
Just like the indexer, you use square brackets for indexed properties:
AA.Filter[0, "market"] = 1;
Which should be supported by dynamic as well. Explicitly calling the setter function would be another way, AA.set_Filter(0, "market", 1).
Note that you'll have a much easier time writing this code when you add a reference to the type library. That lights up IntelliSense and the red squiggles.

Type casting in C# for xamarin

I want to convert NSMutableArray to CLLocationcoordinates2D[]
I tried the following but it gave me an error ,(this kind of type case is not allowed)
NSMutableArray* arrtest ;
// I had added some CLLocationcoordinates2D objects to this
CLLocationcoordinates2D[] locations = (CLLocationcoordinates2D[])arrtest
How could I convert?
If you really have an NSArray which you need to cast in a C# array, do the following:
var locations = NSArray.FromArray<CLLocationCoordinate2D>(arrtest);
However, considering that all Apple APIs in Xamarin.iOS return a C# array instead of an NSArray, you rarely need this. If you created the NSMutableArray yourself, I'd suggest to use a List< CLLocationCoordinate2D> instead.

Dynamically setting type or result from invoked generic method?

My apologies if the question is somewhat unclear; I'm not entirely certain how to phrase this.
My issue is this. I have two classes, Manager<T> and Result<T>. Within Manager<T>, I have a whole raft of retrieval functions. Ordinarily, I would call Manager<T> and set its type like so:
Manager<SpecialDataType> mgr = new Manager<SpecialDataType>;
After which I set up my Result type, and fill it with my function from Manager, where 1 is a parameter for the GetItem function shown. I can then access things in my item:
Result<SpecialDataType> item = new Result<SpecialDataType>;
item = mgr.GetItem(1);
string x = item.Teaser;
OK. So now, what I'm trying to do is set the <SpecificDataType> to be filled in at run time. I think I've got half of the solution already, using generic types, like so:
Type generalType= Type.GetType("SpecificDataType");
Type managerType= typeof(Manager<>).MakeGenericType(generalType);
var managerInstance= Activator.CreateInstance(managerType);
object[] args = {1};
MethodInfo getItemMethod = managerInstance.GetMethod("GetItem");
But here's where I get stuck. There are specific properties that my Result class has that I need to be able to access. They are, or course, set by the data type I'm casting into. When I do an Invoke, like so:
var item = getItemMethod.Invoke(managerInstance, args);
I'm not getting any of my properties that I know are part of item. That makes sense, I suppose, because we don't know what item is. So, we tried this:
Type dataType = typeof(SmartFormData<>).MakeGenericType(sfType);
var item = Activator.CreateInstance(dataType);
item = getItemMethod.Invoke(managerInstance, args);
And got the same result. I can't seem to get to item.Teaser.
I'm not a c# coder natively (as though that's not apparent already from this overly complicated question I'm asking), so I'm not incredibly familiar with reflection and generic types. Can anyone point me in the right direction for how to solve this problem, or how to approach it from a different angle? The only caveat is that I cannot modify the Manager<T> and Result<T> functions; I have to use what I'm given there.
Thanks in advance for any help you can offer.
As Dark Falcon correctly notes in his comment you will have to use reflection to get the members of your item.
Or, if you are in .NET 4 or above, you can use the dynamic keyword to greatly simplify things:
Type generalType= Type.GetType("SpecificDataType");
Type managerType= typeof(Manager<>).MakeGenericType(generalType);
dynamic managerInstance = Activator.CreateInstance(managerType);
var item = managerInstance.GetItem(1);
string x = item.Teaser;
You need to cast the invocation result to the type you're expecting
var item = (Result<SpecificDataType>)getItemMethod.Invoke(managerInstance, args);

Dynamically Casting Objects

Hello everyone I am trying to cast two objects to, both, a specific type based on property reflection information. I want to do this dynamically so I don't need a bunch of switch cases and such for each type that the two objects can be in this class. Overall they will mostly be int or float. At the moment I currently tried using 'var' and 'object' keywords to hold the incoming adjustment value and the properties original value.
// .. snip
/* Get property information. */
PropertyInfo propInfo = classObj.GetType().GetProperty("property-name");
if (propInfo == null)
continue;
/* Prepare object values. */
object orgVal = propInfo.GetValue( classObj, null );
object adjVal = Convert.ChangeType( strAdjust, propInfo.GetType(), new CultureInfo("en-us"));
// .. math on objects here
// ex. orgVal += adjVal;
// .. snip
The incoming adjustment value is in a string but is either in 'int' or 'float' format so it will be easily converted. All of this works fine, it's just the casting to be allowed to adjust the original value with the new adjustment value that is the issue.
I know with .NET 4.0 there is the 'dynamic' keyword that would be able to accomplish something like this, but currently I am stuck using 3.5.
Both objects will use the type from the property information propInfo.GetType().
Any help with this would be greatly appreciated, I'm sure I'm probably overlooking a basic thing here to get this accomplished. Thanks in advance.
-CK
Edit:
Forgot to mention, sorry, this is being developed on a Zune HD, so the framework I have access to is fairly limited to what can/can't be used.
C# 3.5 has a class called TypeConverter
http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx
These provide a mechanism of converting from one type to another based on type information.
System.ComponentModel.TypeConverter GetConverter(System.Type type)
is used to get the converter and
public object TypeConverter.ConvertFrom(object value)
does the conversion. There are built in converters for basic types like int and float, and it is possible to write custom converters for your own types.
Microsoft has a guide to writing them here.
http://msdn.microsoft.com/en-us/library/ayybcxe5.aspx
There's a couple of ways you can do this that I can think of. You can use reflection to get the "op_Addition" method (which is basically "operator +"). But the way I'd do it is via Lambdas:
var orgValueParam = Expression.Parameter(propInfo.PropertyType, "lhs");
var adjValueParam = Expression.Parameter(propInfo.PropertyType, "rhs");
var expr = Expression.Add(orgValueParam, adjValueParam);
var func = Expression.Lambda(expr, orgValueParam, adjValueParam).Compile();
var result = func(orgValue, adjValue);
Note: I haven't actually tested this, so I don't know whether it'll work for sure, but that's where I'd start...

Categories