В зависимости от того, чего вы пытаетесь достичь и где у вас есть гибкость в дизайне, есть несколько вариантов. Я пытался охватить те из них, которые, по моему мнению, наиболее вероятно связаны с тем, что вы хотите сделать.
Несколько значений T в одном экземпляре неуниверсального класса
Это в основном то, что вы, кажется, хотите. Однако из-за общего характера вызова метода вам понадобится переменная уровня класса, которая может поддерживать любое возможное значение T
, и вам нужно будет знать T
при сохранении значения для делегата.
Следовательно, вы можете использовать Dictionary<Type, object>
или использовать вложенный тип, который инкапсулирует переменную уровня класса и метод, а затем вместо него использовать List<WrapperType<T>>
.
Затем вам нужно будет найти соответствующего делегата на основе требуемого типа.
class Example {
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//this works because T is provided
private Dictionary<Type, object> getDSMap;
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
getDSMap[typeof(T)] = method;
}
//note, this call needs to know the type of T
public void anotherMethod<T>() {
object getDSObj = null;
if (this.getDSMap.TryGetValue(typeof(T), out getDSObj))
{
GetGridDataSource<T> getDS = getDSObj as GetGridDataSource<T>;
if (getDS != null)
getDS();
}
}
Одно значение T в одном экземпляре неуниверсального класса
В этом случае вы можете сохранить экземпляр делегата в нетипизированном делегате, а затем преобразовать его в соответствующий тип, когда вам это нужно, и вы знаете значение T. Конечно, вам нужно знать T, когда сначала вы создаете делегат, что сводит на нет необходимость в универсальном методе или делегате.
Несколько значений T в нескольких экземплярах универсального класса
Здесь вы можете сделать свой родительский класс родовым и предоставить T заранее. Это затем приводит к тому, что у вас работает правильно, так как тип T известен с самого начала.
class Example<T> {
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//this works because T is provided
private GetGridDataSource<T> getDS;
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
getDS = method;
}
public void anotherMethod() {
if (getDS != null)
getDS();
}
}