All, have I gone mental (this is not the question). I want to convert List<string[]> to List<object[]>
List<string[]> parameters = GetParameters(tmpConn, name);
List<object[]> objParams = parameters.OfType<object[]>();
this is not working, but unless I have forgotten something a conversion using this method should be possible (no Lambdas needed)?
Thanks for your time.
You want to use something like:
List<object[]> objParams = parameters.OfType<object[]>().ToList();
or in C# 4.0, just
List<object[]> objParams = parameters.ToList<object[]>();
or
List<object[]> objParams = parameters.ConvertAll(s => (object[])s);
Because of array covariance, in .NET 4.0, you can just do:
// Works because:
// a) In .NET, a string[] is an object[]
// b) In .NET 4.0, an IEnumerable<Derived> is an IEnumerable<Base>
var result = parameters.ToList<object[]>();
But note that you wouldn't be able to mutate those arrays with anything other than strings (since array covariance isn't truly safe).
If you want truly flexible writable object arrays, you can do:
var result = parameters.Select(array => array.ToArray<object>())
.ToList();
(or)
var result = parameters.ConvertAll(array => array.ToArray<object>());
Then you could replace the elements of each inner array with instances of pretty much any type you please.
OfType<string[]> returns an IEnumerable<string[]>, not a List<object[]>.
Enuemrable.OfType filters out any invalid casts. You may want to consider Enumerable.Cast instead ,which will throw if you make a mistake. If string[] doesn't inherit from object[] (I honestly don't remember), you may need to call Enumerable.Select to provide a conversion.
You definately need a Enumerable.ToList call in there somewhere.
How about doing it this way
List<string[]> sList = new List<string[]> {new []{"A", "B"}};
List<object[]> oList = sList.Cast<object[]>().ToList();
Related
I need a fast way to create immutable Lists in one line just like Java's List.of(), but in C#. What's the equivalent to this syntax?
List<String> strings = List.of("first", "second");
You could use ImmutableList.Create
ImmutableList<string> list = ImmutableList.Create("first", "second");
You could also use AsReadOnly which returns a wrapper for the list:
ReadOnlyCollection<string> readonlyList = new List<string> { "first", "second" }.AsReadOnly();
However, as this is just a wrappper you can always modify the underlying list, so it's not truly immutable.
Try this code:
var strings = new List<string> { "first", "second" };
I tried searching by "C# new string array pass dynamic" but could not find anything relevant.
int[] IDs = someMethodCall();
List<string> values = new List<string>();
foreach (int i in IDs)
{
values.Add(i.ToString());
}
someClass sc = new someClass();
sc.Value = new string[] { "values.string1", "values.string2", ... };
What I'm trying to do is to pass the strings from values to sc.Value, so I don't have to write them out (since I don't what they'll be beforehand).
sc.Value is a string[] as defined by the class I'm using from an API (not written by me).
What is the best way to do this dynamically? In other words, how to pass in dynamic values to a string[] construction?
If I'm not missing something,you can just use ToArray method
sc.Value = values.ToArray();
BTW, you don't even need to create a list in the first place:
sc.Value = someMethodCall().Select(x => x.ToString()).ToArray();
I'm a little confused by the way you word your questioning, but I think you are trying to send your list to an array, which is easily done using the code below:
List<string> values = new List<string>();
sc.Value = values.ToArray();
How about just using the built-in method ToArray:
sc.Value = values.ToArray();
Comes with List, and is an extension method for IEnumerable if you can use LINQ.
I am working with some existing C# code. Essentially, I have a variable which is a List of objects.
Each of the objects, in turn is a string[n]. I know n, and the value is the same for all the objects in the list. What I need to know is how to loop over the list of objects and get, for each item, a
string[n]
I read your question as how to cast an object of compile time type Object to its run time type of string[]. You do that like so:
Object obj = ...;
string[] arr = (string[]) obj;
What about just casting the object to string[]?
string[] arr = (string[])listOfObjects[x];
It sounds like you want the Cast method:
foreach(string[] strings in listOfStringArrays.Cast<string[]>())
{
// ...
}
Use Enumerable.SelectMany. It projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.
var resultantArray = myarray.SelectMany(x => x).ToArray();
Here is my code:
MyClass here = new MyClass();
IEnumerable<MyClass> vats = (IEnumerable<MyClass>)here.All();
The All() method returns IEnumerable<dynamic>. I want to convert it to IEnumerable<MyClass>. The line above doesn;t work, it says Unable to cast object of type 'd__15' to type 'System.Collections.Generic.IEnumerable`1[MyClass]'.
I also tried:
IEnumerable<MyClass> vats = here.All() as IEnumerable<MyClass>;
but it returns null.
Similar to dbaseman's answer (and AKX's comment) I'd use Cast:
IEnumerable<MyClass> vats = here.All().Cast<MyClass>();
You'll need a using directive for LINQ though:
using System.Linq;
at the top of your file. It sounds like you haven't got that if the Select method isn't recognized.
Note that this assumes that each value really is a MyClass reference.
EDIT: If you want to be able to access the values by index, I'd recommend using ToList:
List<MyClass> vats = here.All().Cast<MyClass>().ToList();
While ToArray would work too, I personally favour lists over arrays in most cases, as they're rather more flexible.
EDIT: It sounds like your results are actually full of ExpandoObject. You'll need to create a new instance of MyClass from each item, e.g.
List<MyClass> vats = here.All()
.Select(item => new MyClass(item.Name, item.Value))
.ToList();
or possibly:
List<MyClass> vats = here.All()
.Select(item => new MyClass {
Name = item.Name,
Value = item.Value,
})
.ToList();
That's just an example, which I wouldn't expect to work straight away - we can't do any better than that as we know nothing about how your results are actually being returned.
It does sound like you're in over your head here, I'm afraid.
You just have to cast each individual object:
MyClass[] vats = here.All().Select(item => (MyClass)(dynamic)item).ToArray();
The first thing to work out before you can create a solution is what types the objects will have at run time. Seeing from your comments that they are going to be ExpandoObjects and assuming MyClass does not derive from ExpandoObject you can't use the .Cast<T> method since it only supports casts and not custom conversions.
There's a trick you can use to convert from ExpandoObjects using the JavaScriptSerializer
taking from this link here an extension method that you could use
public static IEnumerable<T> Convert<T>(this IEnumerable<dynamic> self){
var jsSerializer = new JavaScriptSerializer();
foreach(var obj in self){
yield return jsSerializer.ConvertToType<T>(obj);
}
}
in your case then all you have to do is change the Cast in skeets answer to Convert.
List<MyClass> vats = here.All().Convert<MyClass>().ToList();
This is a bit hackish since the JavaScriptSerializer was not meant to do this but it does solve the problem.
I'm looking for something similar to List<T>, that would allow me to have multiple T. For example: List<TabItem, DataGrid, int, string, ...> = new List<TabItem, DataGrid, int, string, ...>().
If you are using .NET 4, you could have a List<Tuple<T1, T2, ...>>
Otherwise, your choice is to implement your own type.
Create a class that defines your data structure, and then do
var list = new List<MyClass>();
Normally you'd just have List<MyClass> where MyClass had all those other ones as members.
If it can have any old type, then you need to use an ArrayList.
If you know ahead of time what you'll have in there, then you should either create your own structure, or use a Tuple.
Looks like you're after List<object>?
Tuples are best if you are using .net 4.0. But if you are working 3.5 or below, multidimensional object array is good. Here is the code. I have added 3 different types in a object array and I pushed the same to list. May not be the best solution for your question, can be achieved with object array and list. Take a look at the code.
class Program
{
static void Main(string[] args)
{
object[,] OneObject = new object[1,3]{ {"C Sharp",4,3.5 }};
List<object> MyList = new List<object>();
MyList.Add(OneObject);
object[,] addObject = new object[1,3]{{"Java",1,1.1}};
MyList.Add(addObject);
foreach(object SingleObject in MyList)
{
object[,] MyObject = (object[,])SingleObject;
Console.WriteLine("{0},{1},{2}", MyObject[0, 0], MyObject[0, 1], MyObject[0, 2]);
}
Console.Read();
}
}
Instead of trying in C# 4, you can give the old version features a chance here.
It seems you don't need a strongly typed collection here, in that case ArrayList is the best option.