How can I create an instance of an arbitrary Array type at runtime?
Use Array.CreateInstance.
How do I create a C# array using Reflection and only type info?
Just to add to Jon's answer. The reason attempt 1 fails is because there's no default constructor for Int32[]
. You need to supply a length. If you use the overload, which takes an array of arguments it will work:
// attempt1
object y1 = Activator.CreateInstance(t, new object[] { 1 }); // Length 1
Create empty array using reflection
Some types you have to trap and handle special, for your case you'd use:
if ( type.IsArray){
var o = Array.CreateInstance(type, size);
}
Programmatically Declare Array of Arbitrary Rank
Use Array.CreateInstance(Type, Int32[])
method to create an array of an arbitrary size.
But the problem, you will have after creating this array is: How do you efficiently access the elements of the array if you don't know its rank?
You may use myArray.GetValue(Int32[]) and myArray.SetValue(Object, Int32[]) but I assume the performance is no that good.
To sum up:
public static Array CreateArray(Array array)
{
// Gets the lengths and lower bounds of the input array
int[] lowerBounds = new int[array.Rank];
int[] lengths = new int[array.Rank];
for (int numDimension = 0; numDimension < array.Rank; numDimension++)
{
lowerBounds[numDimension] = array.GetLowerBound(numDimension);
lengths[numDimension] = array.GetLength(numDimension);
}
Type elementType = array.GetType().GetElementType(); // Gets the type of the elements in the input array
return Array.CreateInstance(elementType, lengths, lowerBounds); // Returns the new array
}
Update
I've done a little benchmark to compare performance of the array indexer and the GetValue, SetValue versions.
Here is the code I used:
const int size = 10000000;
object[] array1 = new object[size];
object[] array2 = new object[size];
Random random;
random = new Random(0);
for (int i = 0; i < size; i++)
{
array1[i] = random.Next();
array2[i] = random.Next();
}
Stopwatch stopwatch = new Stopwatch();
Console.ReadKey();
stopwatch.Restart();
for (int i = 0; i < size; i++)
array1[i] = array2[i];
stopwatch.Stop();
Console.WriteLine("Indexer method: {0}", stopwatch.Elapsed);
random = new Random(0);
for (int i = 0; i < size; i++)
{
array1[i] = random.Next();
array2[i] = random.Next();
}
Console.ReadKey();
stopwatch.Restart();
for (int i = 0; i < size; i++)
array1.SetValue(array2.GetValue(i), i);
stopwatch.Stop();
Console.WriteLine("Get/SetValue method: {0}", stopwatch.Elapsed);
The result are:
Indexer method: 0.014 s
Set/GetValue method: 1.33 s
The result are slightly different if I replace the int
by object
.
Indexer method: 0.05 s
Set/GetValue method: 0.54 s
This can be easily explained by the necessary boxing/unboxing when using integer with Set/GetValue
.
How to generate array type using a given type?
To get type from its string name you can use Type.GetType method.
To get array type from item use Type.MakeArrayType instance method:
string itemTypeName = "System.Int32";
Type itemType = Type.GetType(itemTypeName);
Console.WriteLine(itemType.MakeArrayType());
Instantiate an object with a runtime-determined type
There are several ways you can create an object of a certain type on the fly, one is:
// determine type here
var type = typeof(MyClass);
// create an object of the type
var obj = (MyClass)Activator.CreateInstance(type);
And you'll get an instance of MyClass in obj.
Another way is to use reflection:
// get type information
var type = typeof(MyClass);
// get public constructors
var ctors = type.GetConstructors(BindingFlags.Public);
// invoke the first public constructor with no parameters.
var obj = ctors[0].Invoke(new object[] { });
And from one of ConstructorInfo returned, you can "Invoke()" it with arguments and get back an instance of the class as if you've used a "new" operator.
How to create a new object instance from a Type
The Activator
class within the root System
namespace is pretty powerful.
There are a lot of overloads for passing parameters to the constructor and such. Check out the documentation at:
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
or (new path)
https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance
Here are some simple examples:
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
How to create Bounded instance based on runtime values?
I wrote a long answer about Hasochism's Matrix
's Applicative
instance, using finite sets as index types, but it's probably overkill for what you wanted, not to mention less efficient than the Array
-based code in the blog post.
Your problem stems from the fact that various operations in the blog post's code assume that the Bounded
instance for the matrix's index type is covering, in the sense that every value within the bounds will have a corresponding element in the matrix. The core assumption seems to be that the size of the matrix is known statically.
The simplest way to fix this would be to make an adjustment to the Matrix
type, so that it carries its size around with it. You still have to do all your bounds checking dynamically, but I think that's a fairly good trade-off compared to the weightiness of the Hasochism approach.
-- Bounded as an explicit (minBound, maxBound) tuple
type Bounds i = (i, i)
data Matrix i e = Matrix { getBounds :: Bounds i, getMatrix :: Array (Edge i) e }
entireRange :: Ix i => Bounds i -> [i]
entireRange b = range b
matrix :: Ix i => Bounds i -> (Edge i -> e) -> Matrix i e
matrix bounds f = Matrix bounds $ listArray bounds $ map f $ entireRange bounds
This gets stuck, however, when you need to construct a matrix in a type class instance. You can't abstract instances over runtime values: the only thing valid to the left of the =>
in an instance declaration is another type class constraint. In a declaration like
instance Bounded i => Applicative (Matrix i) where
pure x = matrix (const x)
(<*>) = -- ...
we have no choice than to pass the bounds statically in an instance dictionary because the type of pure
doesn't allow us to pass explicit configuration data. This restriction has its ups and downs, but right now it's a definite downer: the fix is to rip all of the classiness out of your code altogether.
Good news, though: you can emulate this explicit dictionary-passing style using the crazy reflection
library, which does evil, magical things to push runtime values into typeclass dictionaries. It's scary stuff, but it does work, and it's safe.
It all happens in the reify
and reflect
combinators. reify
takes a runtime value and a block of code with a constraint depending on the availability of that value and plugs them in to one another. Calls to reflect
inside the block return the value that was passed to reify
outside it.
needsAnInt :: Reifies s Int => Proxy s -> IO ()
needsAnInt p = print (reflect p + 1)
example1 :: IO ()
example1 = reify 3 (\p -> needsAnInt p) -- prints 4
example2 :: IO ()
example2 = reify 5 (\p -> needsAnInt p) -- prints 6
Take a moment to reflect (ha ha) on how weird this is. Usually there's only one class dictionary in scope for each type (overlapping instances notwithstanding). Proxy
has only one value (data Proxy a = Proxy
), so how can reflect
tell two proxies apart, to return different values each time?
Anyway, what's the point of this? Instances can't depend on runtime values, but they can depend on other instances. reflection
gives us the tools to turn a runtime value into an instance dictionary, so this allows us to build instances which depend dynamically on runtime values!
In this case, we're building an instance of Bounded
. We need a newtype
, to make an instance which doesn't overlap with any others:
-- in this case it's fine to just lift the Ix instance from the underlying type
newtype B s i = B i deriving (Eq, Ord, Ix)
Clearly B
can be an instance of Bounded
if i
is - it can get minBound
and maxBound
from i
's instance - but we want to get them from a Reifies
context. In other words, the runtime value we'll be stuffing into the Reifies
dictionary will be a pair of i
s.
instance Reifies s (i, i) => Bounded (B s i) where
minBound = B $ fst $ reflect (Proxy :: Proxy s)
maxBound = B $ snd $ reflect (Proxy :: Proxy s)
I'm using ScopedTypeVariables
crucially to come up with Proxy
values of the correct type.
Now you can write perfectly ordinary code which uses a Bounded
context (even if that context arises due to some other instance), and invoke it with a dynamically built Bounded
dictionary using reify
.
entireRange :: (Ix i, Bounded i) => [i]
entireRange = range (minBound, maxBound)
example3 :: IO ()
example3 = reify (3, 6) myComputation
where myComputation :: forall s. Bounded (B s Int) => Proxy s -> IO ()
myComputation p = print $ map unB (entireRange :: [B s Int])
ghci> example3
[3,4,5,6]
Um, yeah. reflection
can be tricky to use. At the end of the day, it's probably simpler just to not bother with classes.
Related Topics
Regarding Local Variable Passing in Thread
How to Change Time in Datetime
Generating Xml File Using Xsd File
How to Check Whether an Object Has Certain Method/Property
Calculated Column in Ef Code First
Adding Unknown (At Design Time) Properties to an Expandoobject
Is There Windows System Event on Active Window Changed
How to Turn Off or Handle Camelcasing in JSON Response ASP.NET Core
Formatting a Double to Two Decimal Places
How to Test If a Type Is Anonymous
How to Create an Instance of an Arbitrary Array Type at Runtime
How to Urlencode Without Using System.Web
Multiple File-Extensions Searchpattern for System.Io.Directory.Getfiles
How to Solve Operator '!=' Cannot Be Applied to Operands of Type 'T' and 'T'
App.Config for a Class Library
How to Do .Net Binary Serialization of an Object When You Don't Have the Source Code of the Class
How to Deserialize a Unix Timestamp (Μs) to a Datetime from JSON