0

I am trying to create an array of the type that is known and currently set to Type. I have been able to create an IList of the type but I am still able to convert that to an array of the type, getting object[] instead.

object propertyValue; //This needs to be an object since it can be set to any object
Type currentType = PropertyInfo.GetType(); //Example: System.String
propertyValue = GetArray(reader, currentType); //What would this look like to make currentType work?
//Reflection occuring later to set propertyValue to attribute of String[]

Here what I got what working with IList, the issue here is not sure how to cast it to an array of currentType. I also prefer just getting an array back instead:

private IList GetArray(Reader reader, Type currentType)
{
  var returnList = createList(currentType); 
  //reader loop that appends to list
  return returnList;
}

public IList createList(Type currentType)
{
  Type genericListType = typeof(List<>).MakeGenericType(currentType);
  return (IList)Activator.CreateInstance(genericListType);
}
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Clayton G
  • 3
  • 2
  • I think you would need to `Invoke` the appropriate `ToArray` method. – NetMage Aug 23 '18 at 22:37
  • For another option, take a look at my answer to https://stackoverflow.com/questions/51679179/c-sharp-covert-type-into-ienumerable-of-same-type. The second option gets you a reference to a `List` upon which you can call `ToArray()`. However, the underlying List is of the correct type. I don't know of any way to get a correctly typed object reference (`List`), only a reference of type `List` – Flydog57 Aug 23 '18 at 22:40
  • I tried to edit my comment, but ran out of time. The code in my answer calls `.ToList()`, but could easily call `ToArray()` instead. Presto, you have an object of type `MyType[]`, however, you can't get a reference to that object that is typed that way; it will be typed `object[]`. I don't know of any way to get a properly typed object reference (aka variable). – Flydog57 Aug 23 '18 at 22:48

2 Answers2

0

Here's an even easier way:

var stringType = typeof(string);
var anArray = System.Array.CreateInstance(stringType, 5);
var arrayAsArray = (object[]) anArray;

At that point, the variable anArray is typed as an object, but refers to an array of 5 strings. The variable arrayAsArray is typed as object[] and it refers to that same array of strings.

What you can't get (as far as I know) is a variable that it typed MyType[] referring to an array of MyType instances if all you have is typeof(MyType). The compiler creates typed object references at compile time, you don't get to play in that space.

One of the features of the .NET Framework (or flaws, depending on how you look) is that arrays are covariant. There are lots of things that can go bad with array covariance (for example, since the compiler thinks you have an `object[]', it would let you try to add an Elephant instance into your array of strings). However, in this case, it makes your code usable, even if it is somewhat fragile.

Flydog57
  • 6,851
  • 2
  • 17
  • 18
0

It seems you'd like to generate an array of a specified type from a stream of objects. If this is the case then I would approach it like so:

void Main()
{
    var file = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "TestFile.txt");

    var array = GetValues<String>(file).ToArray();

    foreach (var item in array)
    {
        Console.WriteLine(item);
    }
}

private IEnumerable<T> GetValues<T>(String file)
{
    using (StreamReader stream = new StreamReader(file))
    {
        while (true)
        {
            var next = stream.ReadLine();
            if (next == null)
            {
                break;
            }
            yield return (T)Convert.ChangeType(next, typeof(T));
        }
    }
}
Carlo Bos
  • 3,105
  • 2
  • 16
  • 29