Дженерики передачи C# во времени выполнения

У меня есть метод как следующее:

public IEnumerable<T> GetControls<T>()
 : where T : ControlBase
{
 // removed.
}

Я затем создал класс:

public class HandleBase<TOwner> : ControlBase
 : TOwner
{
 // Removed
}

Я хотел бы смочь звонить

GetControls<HandleBase<this.GetType()>>; 

где это использовало бы тип ЭТОГО класса, чтобы передать HandleBase. Это было бы в по существу получать все HandleBase, которые имеют владельца ЭТОГО типа.

Как я могу достигнуть этого?

Править:

Я использую.NET 2.0, таким образом, решения, больше, чем 2,0, не будут работать.

Идея состоит в том, чтобы сделать, чтобы ControlBase имел набор другого ControlBase для "детей". Затем они могут быть запрошены на основе их типа с GetControls<T>(). Это позволило бы мне, например, получило бы весь HandleBase для Формы. Затем я могу взять все их и установить Visible=false или сделать что-то еще с ними. Таким образом я могу управлять детьми определенного типа для набора.

HandleBase<TOwner> требует TOwner, так как он имеет ссылку на "тип владения". Таким образом, можно только добавить что-либо, что расширяет HandleBase до Формы. Иметь смысл?

Спасибо за всю справку!

10
задан TheCloudlessSky 28 June 2010 в 19:37
поделиться

6 ответов

Это характерно для моей реализации, но я смог решить эту проблему, создав сначала неуниверсальную HandleBase , а затем generic HandleBase , поскольку TOwner использовался только в качестве владельца свойства.

Затем, когда я могу вызвать GetControls и получить все HandleBase независимо от владельца.

Спасибо всем за ответы!

0
ответ дан 3 December 2019 в 21:20
поделиться

Вы не можете. Generics - это функция времени компиляции. Вам нужно будет включить тип в метод как неуниверсальный параметр и передать его туда.

2
ответ дан 3 December 2019 в 21:20
поделиться

Вы можете сделать это, указав тип во время компиляции или используя отражение.

Вы можете сделать это с помощью отражения следующим образом:

typeof(SomeClass).GetMethod("GetControls")
    .MakeGenericMethod(typeof(HandleBase<>).MakeGenericType(GetType()))
    .Invoke(someObject, null);

Обратите внимание, что он вернет объект ; вы не сможете преобразовать его в IEnumerable (если вы не знаете, что такое T во время компиляции, и в этом случае нет смысла). Вы можете преобразовать его в IEnumerable .

Однако это плохая идея.
Возможно, для вас есть лучшее решение; пожалуйста, предоставьте более подробную информацию.

14
ответ дан 3 December 2019 в 21:20
поделиться

Вероятно, нет способа сделать то, о чем вы просите. Расширяя ваш пример:

X x = GetControls<HandleBase<this.GetType()>>; 

Каким должен быть тип X здесь? Однако из другой справочной информации кажется, что вам нужно получить список всех элементов управления заданного типа. Это можно сделать, например, так:

public IEnumerable<ControlBase> GetControls(Type type) {
//your logic here
}

В зависимости от ваших других применений и целей вы также можете захотеть вернуть негенеративный IEnumerable.

0
ответ дан 3 December 2019 в 21:20
поделиться

Обратите внимание, что параметры типа не являются переменными. Следовательно, вы не можете использовать переменную вместо параметра типа.

Однако вы можете сделать это с помощью отражения или с помощью специальной конструкции, которая довольно ограничена, но может решить ваш случай:

public class MyClass<TSelf> where TSelf: MyClass<TSelf> {
    public IEnumerable<T> GetControls<T>() where T: ControlBase {
     // removed.
    }

    public void MyCall() {
        GetControls<HandleBase<TSelf>>(); 
    }
}

public class MyConcreteClass: MyClass<MyConcreteClass> {
}
1
ответ дан 3 December 2019 в 21:20
поделиться

Поскольку GetControls () возвращает перечисление, вы можете найти способ отфильтровать полученное перечисление с помощью .OfType , что-то вроде

List<T2> list = controlList.GetControls<T>().OfType<T2>().ToList();

Вы бы нужно какое-то общее ограничение вроде

where T2 : T
0
ответ дан 3 December 2019 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: