C#

时间:2018-12-16 12:58:50

标签: 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 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!");

T是未知的类型/名称空间。

当我尝试语法时:

// This static field syntax isn't allowed, too:
static Type_Delegate TypeMethod = new Type_Delegate(TypeMethodName);

缺少类型参数。

我尝试了几种有关可能语法的想法,但没有成功...

我需要如何更改静态字段语法以使其像假定的那样工作,因此代码能够将通用委托方法设置为值,而不必在那时指定类型?

编辑:我还尝试使用通用静态类包装委托和字段,但是当我想设置字段值而不指定类型时,仍然存在相同的语法问题。

编辑2 :也许以下示例变通方法可以进一步阐明我的想法,因为我认为大多数评论者都不理解我的目标(也许也是我的英语不好):

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!"));

在此示例解决方案中,我需要使用类和接口,需要进行反射,这是一整套代码,以实现通用(类)方法的相同功能,因为我只需两行即可非泛型方法(使用委托)时使用代码。多么大的开销,什么骇客-我试图避免在生产性代码中做如此讨厌的事情。但是,如果没有更好的两行代码能做到这一点,那么这次我将不得不奋斗……

1 个答案:

答案 0 :(得分:0)

可以通过将其包装在通用类定义中并使用类类型参数来实现。

static class C<T>
{
    public static DelegateTypePrototype<T> DelegateType;
}

这样,仅当您“请求”该类的实例时,才需要解析类型。至少这是我对C ++模板背景的直观理解。