런타임에 임의의 배열 유형의 인스턴스를 어떻게 만들 수 있습니까?
-
03-07-2019 - |
문제
컴파일 타임에 알려지지 않은 유형의 배열을 필사적으로 만들려고 노력하고 있습니다. 런타임에 나는 유형을 발견했지만 인스턴스를 만드는 방법을 모르겠습니다.
같은 것 :
Object o = Activator.CreateInstance(type);
매개 변수가없는 생성자가 없기 때문에 작동하지 않으며 배열에는 생성자가없는 것 같습니다.
해결책
다른 팁
배열의 CreateInstance 오버로드 중 하나를 사용할 수 있습니다.
object o = Array.CreateInstance(type, 10);
꽤 오래된 게시물이지만 새로운 질문에 대답하면서 다차원 배열을 작성하는 관련 예제를 게시합니다.
유형을 가정합니다 (elementType
) 처럼 int
예를 들어 2 차원 배열.
var size = new[] { 2, 3 };
var arr = Array.CreateInstance(typeof(int), size);
예를 들어 2 차원이면
var value = 1;
for (int i = 0; i < size[0]; i++)
for (int j = 0; j < size[1]; j++)
arr.SetValue(value++, new[] { i, j });
//arr = [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
대안은 공연을 위해 발현 나무를 사용하는 것입니다. 배열이있는 경우 예를 들어 유형, type
당신은 할 수 있습니다
var ctor = type.GetConstructors().First(); // or find suitable constructor
var argsExpr = ctor.GetParameters().Select(x => Expression.Constant(0));
var func = Expression.Lambda<Func<object>>(Expression.New(ctor, argsExpr)).Compile();
이것은 빈 배열을 반환합니다. 아마도 그다지 유용하지 않을 것입니다. MSDN 상태 GetConstructors
주문을 보장하지 않으므로 올바른 크기로 인스턴스화 할 올바른 매개 변수를 가진 올바른 생성자를 찾으려면 논리가 필요할 수 있습니다. 예를 들어 할 수 있습니다.
static Func<object> ArrayCreateInstance(Type type, params int[] bounds) // can be generic too
{
var ctor = type
.GetConstructors()
.OrderBy(x => x.GetParameters().Length) // find constructor with least parameters
.First();
var argsExpr = bounds.Select(x => Expression.Constant(x)); // set size
return Expression.Lambda<Func<object>>(Expression.New(ctor, argsExpr)).Compile();
}
동일하게 훨씬 쉽게 달성 할 수 있습니다 Expression.NewArrayBounds
대신에 Expression.New
, 배열 유형 자체가 아닌 배열 요소 유형 만 있으면 더 많이 작동합니다. 데모:
static Func<object> ArrayCreateInstance(Type type, params int[] bounds) // can be generic too
{
var argsExpr = bounds.Select(x => Expression.Constant(x)); // set size
var newExpr = Expression.NewArrayBounds(type.GetElementType(), argsExpr);
return Expression.Lambda<Func<object>>(newExpr).Compile();
}
// this exercise is pointless if you dont save the compiled delegate, but for demo purpose:
x = string[] {...
y = ArrayCreateInstance(x.GetType(), 10)(); // you get 1-d array with size 10
x = string[,,] {...
y = ArrayCreateInstance(x.GetType(), 10, 2, 3)(); // you get 3-d array like string[10, 2, 3]
x = string[][] {...
y = ArrayCreateInstance(x.GetType(), 10)(); // you get jagged array like string[10][]
그냥 변경하십시오 type.GetElementType()
간단히 type
당신이 지나가는 것이 요소 유형 자체라면.
제휴하지 않습니다 StackOverflow