2016-08-04 4 views
0

Так что я пытаюсь достичь, по сути, передать тип методу и вернуть IEnumerable этого типа из метода.Как вернуть IEnumerable типа X из метода

Это то, что мне удалось до сих пор:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var x = PassType(typeof(Test)); 
    } 

    public static IEnumerable<dynamic> PassType(Type destType) 
    { 
     var testInstance = new Test() { Name = "Greg", Age = 45, IsSomething = false }; 
     var destinationList = ((IEnumerable<object>)Activator.CreateInstance(typeof(List<>).MakeGenericType(new[] { destType }))).ToList(); 
     destinationList.Add(testInstance); 
     return destinationList; 
    } 
} 
public class Test 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public bool IsSomething { get; set; } 

    public Test() 
    { 

    } 
} 

Однако это, очевидно, возвращая IEnumerable типа динамичны, мне было интересно, есть ли способ вернуть IEnumerable типа Test

Заранее спасибо

+2

Почему вы не используете дженерики? 'IEnumerable x = PassType ();' –

+0

@TimSchmelter Я предполагаю, что OP не знает тип во время компиляции. – HimBromBeere

ответ

2

На самом деле, что вы возвращаетесь являетсяIEnumerable<TheType>, по крайней мере, во время выполнения. Однако вы не можете ожидать компилятора для вывода аргументов типа, которые вы указываете att runtime. Таким образом, компилятор не может знать, из какого типа перечислимый, все это знает, что это что-то dynamic. Вот почему вы не можете вызывать каких-либо членов этого типа в экземплярах в перечислении.

Однако в вашем случае простой общий метод будет делать то, что вы хотите:

var x = PassType<Test>(); 

Какой нужен ваш метод быть похож на это:

IEnumerable<T> PassType<T>() { ...} 

Если вы не знаете, что тип во время компиляции вы можете использовать MakeGenericMethod для вызова общего метода с аргументом типа, переданным во время выполнения:

var theMethod = typeof(Program).GetMethod("PassType").MakeGenericMethod(typeof(Test)); 
var x = theMethod.Invoke(); 

Однако во время компиляции у вас все еще нет знаний о типе, поэтому x имеет тип object. Поскольку IEnumerable<T> является ковариантным с .NET 4.0, вы можете указать его IEnumerable<object> или IEnumerable<MyBaseClass>, если все ваши типы реализуют MyBaseClass. Но вы никогда не получите IEnumerable<MyType> во время компиляции и вызовите членов этого типа непосредственно в экземплярах.

+0

Это работает, спасибо большое – ASMoncrieff

0

Я думаю, вам стоит взглянуть на Generics in C#.

Подробнее: Generics

+0

Вам следует подумать о том, чтобы написать соответствующую информацию из этой статьи в ответ или ответить на этот вопрос. – HimBromBeere

Смежные вопросы