C# C中的静态泛型委托字段#
使用泛型类型很好,也很简单,但自从我尝试实现自己的泛型类型后,我遇到了一个我自己还无法解决的问题。我想为委托创建一个静态字段。这就是我在使用非泛型类型时的工作方式:C# C中的静态泛型委托字段#,c#,generics,C#,Generics,使用泛型类型很好,也很简单,但自从我尝试实现自己的泛型类型后,我遇到了一个我自己还无法解决的问题。我想为委托创建一个静态字段。这就是我在使用非泛型类型时的工作方式: delegate Type Type_Delegate(Type type); static Type_Delegate TypeMethod = new Type_Delegate(TypeMethodName); // Now the TypeMethod can be called like this from somewh
delegate Type Type_Delegate(Type type);
static Type_Delegate TypeMethod = new Type_Delegate(TypeMethodName);
// Now the TypeMethod can be called like this from somewhere in the Code:
ClassName.TypeMethod(typeof(string));
但在使用任何泛型类型时:
delegate T Type_Delegate<T>(T type);
// This static field syntax isn't allowed:
static Type_Delegate<T> TypeMethod = new Type_Delegate<T>(TypeMethodName);
// It would be a dream to be able to use it like this now:
ClassName.TypeMethod<string>("Hello world!");
用法缺少类型参数
我尝试了一些关于可能的语法的想法,但没有成功
我需要如何更改静态字段语法才能按假定的方式工作,以便代码能够将泛型委托方法设置为值,而不必在此时指定类型
编辑:我还尝试用通用静态类包装委托和字段,但在这里,当我想设置字段值而不指定类型时,仍然存在相同的语法问题
编辑2:也许下面的示例解决方法apporach会更清楚地阐明我的想法,因为我认为大多数评论者不理解我的目标(可能也是我的英语不好):
在这个示例解决方案中,我需要使用类和接口,需要反射,这需要一大堆代码才能为泛型(类)方法获得相同的功能,因为在使用非泛型方法(使用委托)时,我只能使用两行代码。多大的开销啊,多大的黑客行为啊——我尽量避免在高效的代码中做这种讨厌的事情。但是,如果没有更好的两行代码可以做到这一点,那么这次我将不得不与我的自我抗争……这是可能的,方法是将它包装在通用类定义中并使用class type参数
static class C<T>
{
public static DelegateTypePrototype<T> DelegateType;
}
静态C类
{
公共静态委托类型原型委托类型;
}
这样,只有在“请求”该类的实例时才需要解析该类型。至少这是我的直觉理解来自C++模板背景。泛型类型的值需要在编译时确定。同样,您不能实例化
列表
。初始化时,类型参数类型必须为determined@Rotem从理论上讲,从逻辑上讲,这是可能的。但也许它还没有在编译器中实现。“理论上,从逻辑上讲,这应该是可能的。”我不知道你的意思。语言完全禁止它。请注意,除此之外,字段不能是泛型的。如果将该字段放在声明类型参数的泛型类中,它至少会删除第一个问题……这没有意义,因为静态变量属于类而不是实例。这是一种更干净的解决方案。它将为使用的每种类型的T
初始化C
的静态实例及其成员,但我不必使用慢速反射和“动态”。缺点是,对于可能用于T
的每个类型,我必须为DelegateType
设置委托。
using System;
using System.Linq;
using System.Reflection;
namespace Testing
{
public static class GenericTest
{
public interface IGenericClass<T>
{
T Method(T parameter);
}
public class GenericClass<T> : IGenericClass<T>
{
public T Method(T parameter)
{
// Just a stupid example, don't think about that...
return parameter;
}
}
/// <summary>
/// The value must be any type that implements the IGenericClass<T> interface
/// </summary>
public static Type GenericField = typeof(GenericClass<>);
/// <summary>
/// Call the method of an instance of the type that was set to GenericField
/// </summary>
/// <param name="T">The type to use for creating an instance of the generic class</param>
/// <param name="parameter">The parameter for calling the method of the generic class</param>
/// <returns>Any value of type "T"</returns>
public static dynamic GenericMethod(Type T, object parameter)
{
var genericType = GenericField.MakeGenericType(new Type[] { T });
MethodInfo method = genericType.GetMethod("Method");
if (method == null) throw new InvalidCastException("GenericField isn't a IGenericClass<T> type");
return method.Invoke(Activator.CreateInstance(genericType), new object[] { parameter });
}
}
}
MessageBox.Show(Testing.GenericTest.GenericMethod(typeof(string), "Hello world!"));
static class C<T>
{
public static DelegateTypePrototype<T> DelegateType;
}