Issue with out system.Array Conversion for solidworks plugin C# - c#

I just got thrown into a C# project for solidWorks that I'm not too comfortable with. I need to convert this out System.Array to a string[]. Then that string is called and converted from out System.Array to out EdmLib.EdmBatchError2[].
TLDR: out System.Array' to a string[].
Code:
private void GetSerialNumberGenerators()
{
IEdmSerNoGen7 utility = this.m_vault.CreateUtility(EdmUtility.EdmUtil_SerNoGen) as IEdmSerNoGen7;
Array ppoRetNames = Array.CreateInstance(typeof(string[]), 0);
utility.GetSerialNumberNames(out ppoRetNames);
this.comboBoxSerialNumber.DataSource = (object) ppoRetNames;
}
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'out System.Array' to 'out string[]'

It's simple as
string[] ppoRetNames;
GetSerialNumberNames(out ppoRetNames);
This is the way to declare a string[]. Don't initialize it yourself because GetSerialNumberNames will do it (out-parameter). No need to use Array.CreateInstance.
Apart from that you are creating a jagged array because you pass typeof(string[]) not typeof(string). You need a one dimensional array so this would be correct:
Array someArray = Array.CreateInstance(typeof(string), 0);
string[] ppoRetNames = (string[])someArray; // so a cast is what was missing

GetSerialNumberNames returns System.Array of type EdmBatchError2, which is a structure of 4 ints, so I don't know how that would cast to a string[] in a usable sense. Here is what I do:
utility.GetSerialNumberNames(out Array ppoRetNames);
foreach(EdmBatchError2 batchError in ppoRetNames) {
// construct error message with below variables for each error
//batchError.mlFileID;
//batchError.mlFolderID;
//batchError.mlVariableID;
//batchError.mlErrorCode;
}

Related

C# Two Dimensional Array and Array.Find - Cannot Convert Error

I have a two dimensional array declared. It has two columns - filename and batch. I initialize it empty.
string[,] a_Reports = new string[,] { { "", "" } };
I have some code that resizes it and populates it. Everything is a string value. When I go to look up an element in the array like so:
int value1 = Array.Find<string>(a_Reports, element=>element.Equals(newFileName));
I get the error:
CS1503 Argument 1: cannot convert from 'string[*,*]' to 'string[]'
I've tried it every which way and nothing works. Please help me!!! I've spent hours on it already.
Array.Find is only for one-dimensional arrays. (MSDN)
Check out this answer on 'How do I search a multi-dimensional array?'
Produce a similar extension method, like in my example on rextester.
Or use a jagged array instead of a two-dimensional one and a combination of foreach and find, like:
string[][] jagged = ...
Array.ForEach(jagged, array=>Array.Find(array, x=>x=="" ));

How to convert this code from Unityscript to C#?

I am trying to convert Unity UnityScript to C#. I am getting this error:
Assets/Scripts/BoostPlatformCheck.cs(40,36): error CS0019: Operator
==' cannot be applied to operands of typeint' and `object'
Here is the C# code:
int collidedWith = collisionInfo.gameObject.GHetInstanceID();
ArrayList collided = new ArrayList();
....
if(collidedWith == collided[collided.Count - i - 1])
{
alreadyExists = true;
return;
}
I changed Array to ArrayList and collided.length to collided.Count when I converted it from JS to C#.
I changed Array to ArrayList and collided.length to collided.Count
when I converted it from JS to C#
Since you just want to convert the code to C#, use array of int instead of ArrayList:
int[] collided = new int [10]; // This is how you declare arrays in C#
Then you can just use collided.length like in Javascript to find the length of the array.
Also one more thing, arrays in C# has a built in function Contains() that may help you in your case, which seems like you're iterating over the array to compare collidedWith. To simplify, you can remove the loop and try this:
// This means collidedWith exists within collided, so you won't need the loop anymore
if(collided.Contains(collidedWith))
alreadyExists = true;

Convert list to int array in C#

I have searched through StackOverflow and Google for the conversion, but unfortunately I was unable to get the solution. Everything was the opposite of what I wanted. i.e., Conversion of an int[] to List.
Problem
I have this code in my [WebMethod].
[WebMethod]
public int MyMethodWS(int N, List<int> M)
{
}
And now I have a Console Application, that references this service by using this URL:
http://localhost:61090/MyMethod.asmx?WSDL
I have this code in my Console Application:
int N;
List<int> M = new List<int>();
// Some crazy user input coding.
// Ultimately you will have non-empty M list and N int.
MyMethod.MyMethodWS DA = new MyMethod.MyMethodWS();
Sum = DA.MyMethodWS(N, M);
When I run this code, I am getting this error:
#1: The best overloaded method match for 'MyMethod.MyMethod.MyMethodWS(int, int[])' has some invalid arguments.
#2: Argument 2: cannot convert from 'System.Collections.Generic.List<int>' to 'int[]'
Questions
I have used only List there. But why is it trying to convert as int[]?
Currently the WebService as well as Console Application, both run in the same Solution. Is it a problem? Should I use different solutions, or different instances of Visual Studio 2012 altogether?
It is trying to convert it to int[], because MyMethodWS takes a int[] as a parameter, instead of List<int> that you are trying to pass it. To convert a List<int> to int[], call List<T>.ToArray();
So change the line Sum = DA.MyMethodWS(N, M); to Sum = DA.MyMethodWS(N, M.ToArray());

MS Word Automation in C# - Unable to cast object of type 'System.String[*]' to type 'System.String[]'

I use this code to get a String array of headings used in a MS Word 2007 document (.docx):
dynamic arr = Document.GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);
Using the debugger, I see that arr is dynamically assigned a String array with titles of all my headings in the document (about 40 entries). So far so good.
Then, I want to access the strings, but no matter how I do it, I get the following exception:
InvalidCastException:
Unable to cast object of type 'System.String[*]' to type 'System.String[]'.
I have tried different ways of accessing the strings:
By index:
String arr_elem = arr[1];
By casting to an IEnumerable:
IEnumerable list = (IEnumerable)arr;
By using a simple foreach loop:
foreach (String str in arr)
{
Console.WriteLine(str);
}
However, no matter what I try, I always end up with the same exception as shown above.
Can anyone explain what I am missing here / what I am doing wrong? And especially String[*] - what does it mean?
string[] is a vector - a 1-d, 0-based array. string[*], however, is a regular array that just happens to have one dimension. Basically, you are going to have to handle it as Array, and either copy the data out, or use the Array API rather than the string[] API.
This is the same as the difference between typeof(string).MakeArrayType() (the vector) and typeof(string).MakeArrayType(1) (a 1-d non-vector).
try
object arr_r = Document.GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);
Array arr = ((Array) (arr_r));
string myHeading = (string) arr.GetValue(1);
The problem is that you're using dynamic in a situation where it apparently wasn't intended. When the dynamic runtime sees a 1D array, it assumes a vector, and tries to index into it or enumerate it as if it were a vector. This is one of those rare cases where you have a 1D array that is not a vector, so you have to handle it as an Array:
Array arr = (Array)(object)Document.
GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);
// works
String arr_elem = arr.GetValue(1);
// now works
IEnumerable list = (IEnumerable)arr;
// now works
foreach (String str in arr)
{
Console.WriteLine(str);
}

Converting a List<> to an Array - I get "Attempted to access an element as a type incompatible with the array."

I'm trying to walk through a bunch of items, each item has an array of List<> objects that I want to convert to an array of arrays.. Here's the code to do that:
foreach (IngredientNode i in _snapshot._ingredientMap.Values)
{
for (int c = 0; c < NUM_TAGS; c++)
{
if (i.RecipesByTag[c] == null) continue;
i.RecipesByTag[c] = i.RecipesByTag[c].ToArray<RecipeNode>();
} <--- EXCEPTION
}
RecipesByTag has a static type of IEnumerable<RecipeNode>[]. However, its dynamic type is List<RecipeNode>[]. I want to go through each one of those and convert the dynamic type of RecopeNode[]. Under the debugger, this works and i.RecipesByTag gets converted. However, the last curly brace then throws the exception:
Attempted to access an element as a type incompatible with the array.
I have a feeling there's some sort of stack corruption going on. Can someone explain what's happening at a technical level here? Thanks!
Mike
You shouldn't have to specify the type argument for the ToArray method, it should be inferred from it's usage, if you are using strongly typed collections. This is a generic type casting problem. You are trying to put elements in an array of some incompatible type.
Your problem should boil to this (these arrays are covariant):
object[] obj = new string[1];
obj[0] = 5; // compiles fine, yields runtime error
Now, the same thing, with different types (these arrays are also covariant):
IEnumerable<int>[] x = new List<int>[1];
x[0] = new int[1]; // compiles fine, yields runtime error
It should be obvious why the type system doesn't like this. Basically, you look at it as if it was an array of IEnumerable<int> but it's actually an array of List<int>. You can not put an unrelated type array of int, into that array.
I believe Eric Lippert explains this very well on his blog.
Okay I think I figured out what's going on.. I have an array of Enumerables. At first, this was an array of pointers to list objects. I instead made this an array of other arrays, in other words I converted my array into a multidimentional array. Since a multidimentional array is consecutive in memory (as opposed to an array of pointers to other arrays), doing this completely corrupted the array in memory. At least that's my theory.
What I did is completely recreate i.RecipesByTag from scratch. Something like this:
List<RecipeNode[]> temp = new List<RecipeNode[]>();
for (int c = 0; c < NUM_TAGS; c++)
{
RecipeNode[] nodes = (i.RecipesByTag[c] == null) ? null : i.RecipesByTag[c].ToArray<RecipeNode>();
temp.Add(nodes);
}
i.RecipesByTag = temp.ToArray();
This works perfectly.

Categories