我遇到了另外一个问题:Using an IEnumerable<T> as a delegate return type
从上述解决方案中,建议如下:
class Example
{
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
method();
}
//a method to pass to "someMethod<T>"
private IEnumerable<string> methodBeingCalled()
{
return Enumerable.Empty<string>();
}
//our main program look
static void Main(string[] args)
{
//create a new instance of our example
var myObject = new Example();
//invoke the method passing the method
myObject.someMethod<string>(myObject.methodBeingCalled);
}
}
请注意,在someMethod中,调用委托“method()”。无论如何设置一个稍后调用的类级代理?
即:
class Example {
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//this fails because T is never 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() {
getDS();
}
}
答案 0 :(得分:2)
根据您要实现的目标以及设计的灵活性,有许多选择。我试图掩盖那些我认为最可能与你想做的事情有关的事情。
这基本上就是你想要的。但是,由于方法调用的通用特性,您需要一个可以支持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的类型。
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();
}
}
答案 1 :(得分:0)
您需要将类型设置为泛型,或者使用普通Delegate
并在需要调用时转换回正确的类型。您不能只在通用上下文之外使用T
- 编译器会认为您正在尝试引用名为T
的普通类型。
换句话说 - 如果您打算在两个不同的地方尝试使用相同类型的T
,那么您需要知道T
在某个类型中的位置......如果类型不是通用的,那么该信息将存在于哪里?