I'm using a visual basic library and one of the methods I'm using calls for a System.Array to be passed into it.
I've tried using "double[]" and "Object[]" when declaring my array however those will not pass.
I'm not sure how to convert/declare a "System.Array".
Object[] filledVals = new Object[9];
xyz.getDoubleArray("NumVoids", out filledVals); //where .getDoubleArray(string, System.Array)
Simply declare it as System.Array:
Array filledVals;
xyz.getDoubleArray("NumVoids", out filledVals);
Since it is an out parameter, you don't need to initialize it as it must be initialized by getDoubleArray.
To convert it to a double[] you can use this:
double[] result = filledVals.OfType<double>().ToArray();
You can use LINQ:
System.Array result;
xyz.getDoubleArray("NumVoids", out result);
var filledVals = result.OfType<double>().ToArray();
Related
Try:
Array[] UserInformation;
UserInformation[0] = "Test";
but i get a error Cannot implicitly convert string to System.Array
But this works:
string[] asp;
asp[0] = "ram";
I don't want to use string[] or int[] because I have to assign different data types in each index.
If its not the right way to add items to an array please suggest the correct way?
Array is a type that exists in the BCL - you are looking for an object array, which you also need to initialize:
object[] UserInformation = new object[10];
UserInformation[0] = "Test";
Array[] UserInformation;
This declares UserInformation as an array of arrays... A string is not an array.
You'll need to create an array of "object", since everything in C# inherits from that base class.
object[] anArray = new object[];
my function has the following signature
function myfunction(ref object)
I use it as such
Array arr = Array.CreateInstance(System.Type.GetType("System.String"), 2);
arr.SetValue("1", 0);
myfunction( ref arr);
And I am getting
"cannot convert from 'ref System.Array' to 'ref object'"
I was under the impression that System.Array is object ...so why am I getting this error? Is object different from Object?
The problem you're having is that while an array is an object, an object is not an array, so in your function, if your array could be passed in as a ref object, the array could be assigned anything that is an object.
Edit:
To fix this problem declare a ref variable to use in place of the array variable:
Array arr = Array.CreateInstance(System.Type.GetType("System.String"), 2);
arr.SetValue("1", 0);
object referenceObject = arr;
myfunction( ref referenceObject );
Think of 'ref object' as "I take a reference to a variable that can store an Object". Suppose that 'myfunction' tried to store an 'int' to the variable you passed? This would fail at runtime, which is undesirable.
On a side note, you can use typeof(string) in place of calling GetType("System.String"). You can also just say:
Object arr = new string[2];
To access the array first, you can do this:
string[] arr = new string[2];
arr[0] = "1";
object arrObj = arr;
myfunction(ref arrObj);
I would double check that you're using the method myfunction correctly; it's a rather unusual parameter type for taking an initialized array.
Declare the variable as object and not as array.
To populate the array with values you should keep your array variable and declare another one to give it to the method.
Array myArray = ....;
Object myObject = myArray;
myFunction(ref myObject);
// Update the original reference
myArray = myObject as Array;
I've got a function which takes a ArrayList and loads it with strings along the line of
void func( ref ArrayList data )
{
if( data[0].GetType() == typeof(String) )
data[0] = "Jimmy";
}
In the function that calls func() I am having to create strings to put in the array:
ArrayList data = new ArrayList(1);
string str = "";
data.Add(str);
Is it possible to give the ArrayList the object types without having to create an object of that type? This:
ArrayList data = new ArrayList(1);
string str;
data.Add(str);
Gives a "Use of unassigned local variable 'str'" error.
#James and Guffa: Thanks for the 'stylistic' hints, I'm new to c# and the advice is much appreciated
No, that is not possible. What you want is a reference that points to a string, and that is only possible if it actually points to a string. The fact that the variable that holds the reference is declared as a string reference doesn't matter once you have copied the reference from the variable to the list.
I think that you should rethink the entire concept. I don't know your reason for sending in a list of values and replace them like that, but there has to be a more object oriented way of doing it.
The ArrayList class is practically obsolete, you should use a generic List<T> instead (even if you can't find any other common base class than object).
As you are always sending in a list object to the method and not replacing it with a new list object, you should not use the ref keyword. That's only for when you want to change the reference to the list, not the contents of the list.
You can send two parameters, one ref ArrayList in which members will be assigned and the other an ArrayList and the called function can assign at indexes in data where the type is String
If you are only wanting to keep this type safe then could you not use a List<T> class here instead e.g. List<string>?
What you're trying to do in your method with the above code is to call GetType() on null, which is not possible.
Why not use a generic list List<string> in this case? You can elegantly skip the part of using GetType() to determine the type with this approach:
static void func(List<string> data)
{
if(data.Count > 0)
data[0] = "Jimmy";
}
static void Main(string[] args)
{
List<string> lst = new List<string>(1);
string str = "";
lst.Add(str);
func(lst);
System.Console.WriteLine(lst[0]); //Prints out 'Jimmy'
}
What is the best way to convert a JavaScript array of doubles
return [2.145, 1.111, 7.893];
into a .NET array of doubles, when the Javascript array is returned from a webbrowser controls document object
object o = Document.InvokeScript("getMapPanelRegion");
without using strings and parsing?
The object returned is of type __ComObject as it is an array being returned. The array will be a fixed size as I am using this to return three values back to the calling code. My current solution is to return a | deliminated string of the three value, I then split and parse the string to get my three doubles. If possible I would like to not have to use the string manipulation as this feels like a hack.
From MSDN (HtmlDocument.InvokeScript Method):
The underlying type of the object returned by InvokeScript will vary. If the called Active Scripting function returns scalar data, such as a string or an integer, it will be returned as a string ...
It seems that integers will be returned as string, you could asume that the same applies to doubles.
EDIT:
I forgot that you were talking about an array. Anyhow, MSDN continues:
... If it returns a script-based object, such as an object created using JScript or VBScript's new operator, it will be of type Object ...
So it seems that you will get an object instead, but that doesn't help the fact that you will have to convert it inside your C# code.
EDIT 2:
As for the conversion of the actual ComObject. After reading this which is about Excel, but it still returns a ComObject, it seems that your current aproach with the string seems like the simpler one. Sometimes a hack is the best solution :D
This "problem" amounts to transforming VARIANT into an C# array. For this probably the easiest way is to use reflection. Here is how:
private static IEnumerable<object> SafeArrayToEnmrble (object comObject)
{
Type comObjectType = comObject.GetType();
// spot here what is the type required
if (comObjectType != typeof(object[,]))
// return empty array, throw exception or whatever is your fancy
return new object[0];
int count = (int)comObjectType.InvokeMember("Length", BindingFlags.GetProperty, null, comObject, null);
var result = new List<object>(count);
var indexArgs = new object[2];
for (int i = 1; i <= count; i++)
{
indexArgs[0] = i;
indexArgs[1] = 1;
object valueAtIndex = comObjectType.InvokeMember("GetValue", BindingFlags.InvokeMethod, null, comObject, indexArgs);
result.Add(valueAtIndex);
}
return result;
}
I'm using a third party library. One of the methods requires passing an array via ref that will be populated with some info. Here's the definition for the method:
int GetPositionList(ref Array arrayPos)
How do I construct arrayPos so that this method will work? In the library's not so complete documentation it defines the method as such:
long GetPositionList(structSTIPosUpdate() arrayPos)
I've tried this but of course I'm getting errors:
System.Array position_list = new System.Array();
sti_position.GetPositionList(ref position_list);
Any ideas?
This is the Sterling Trader Pro ActiveX API, right? Did you create an Interop dll using tlbimp.exe? The GetPositionList API expects an array which will hold structs of type structSTIPositionUpdate. Normally an out modifier is used if the callee initializes the passed-in data, and ref if the data is to be initialized. According to the meaning of the API the modifier should be out, so that this should work:
structSTIPositionUpdate [] entries = new structSTIPositionUpdate[0]; // or null
num_entries_returned = GetPositionList(ref entries);
Alternatively, try creating an array of these structs which is big enough to hold the expected number of entries, then pass it to the function:
structSTIPositionUpdate [] entries = new structSTIPositionUpdate[100]; // say
num_entries_returned = GetPositionList(entries);
Update: If you are getting type mismatches with System.Array, try
System.Array entries = Array.CreateInstance(typeOf(structSTIPositionUpdate), N);
where N is the number of elements in the array.
To create an instance of an Array you can use the CreateInstance method:
Array a = Array.CreateInstance(typeof(Int32), 10);
GetPositionList(ref a);
The type, dimension and size of the array is something the library author should document. The GetPositionList may be badly designed and simply create a new Array for you essentially meaning that the library author should have used out instead of ref. In that case you can use a null array:
Array a = null;
GetPositionList(ref a);
You can use Array.CreateInstance
This may help you:
http://msdn.microsoft.com/en-us/library/szasx730%28VS.80%29.aspx
...although I don't understand why an object needs to have the "ref" keyword. Objects are passed by reference, so this should work anyway, without making use of the ref keyword. For arrays like int[] or string I understand this...
This works:
Array position_list = new int[]{1, 3, 5, 5,6};
sti_position.GetPositionList(ref position_list);
I also using Sterling Trader API. I use this code:
private structSTIPositionUpdate[] PositionList {
get {
Array arrayPos = null;
_position.GetPositionList(ref arrayPos);
return (structSTIPositionUpdate[]) arrayPos;
}
}