简体   繁体   中英

C# Generic interface

I need to pass a generic type parameter to an interface. I have a string with the name of the type.

I have something like this:

string type = "ClassType";
Type t = Type.GetType("ClassType");

IProvider<t> provider = (IProvider<t>)someObject;

This doesn't work for me. What is the correct way to do it? Thanks.

What' you're trying to do is not really possible in the C# (and CLR) version of generics. When specifying a generic parameter it must be either ...

  • A Concrete type in code
  • Another generic parameter

This information must be bound in the metadata of the assembly. There is no way to express a type name from string in metadata in this fashion.

It is possible to bind a generic at runtime based on string names but this requires reflection.

我相信这就是你要找的东西=> Type.MakeGenericType

Here is a sample using reflection to load a generic type.

using System;
namespace GenericCastRuntime
{
    class Program
    {
        static void Main(string[] args)
        {
            string type = "GenericCastRuntime.Program+Provider`1";
            Type t = Type.GetType(type);

            string genericType = "System.String";
            Type gt = Type.GetType(genericType);

            var objType = t.MakeGenericType(gt);
            var ci = objType.GetConstructor(Type.EmptyTypes);
            var obj = ci.Invoke(null);
            IProvider provider = obj as IProvider;
        }

        public class Provider<T> : IProvider<T>
        {
            public T Value { get; set; }

            object IProvider.Value
            {
                get { return this.Value; }
                set
                {
                    if (!(value is T)) throw new InvalidCastException();
                    this.Value = (T)value;
                }
            }

        }

        public interface IProvider { object Value { get; set; } }
        public interface IProvider<T> : IProvider { T Value { get; set; } }
    }
}

Here's a simple example:

    public static object DynamicallyCreateGeneric(Type GenericTypeSource, Type SpecificTypeSource)
    {
        System.Type SpecificType = 
            GenericTypeSource.MakeGenericType(
            new System.Type[] { SpecificTypeSource }
            );

        return Activator.CreateInstance(SpecificType);
    }

...then, for example:

        string type = "System.String";
        Type t = Type.GetType(type);

        var DynamicallyCreatedGeneric = DynamicallyCreateGeneric(typeof(List<>), t);

        System.Diagnostics.Debugger.Break();

Adapt to suit your implementation and to taste. Of course, this method is not ideal. One of the best parts of generics is type compiler level type safety.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM