returns 泛型参数基础类型的扩展方法

Extension method that returns underlying type of generic argument

我正在尝试编写 IThingRequest<TEntity> 的扩展方法,它 returns Thing<TEntity>。我希望该方法仅 return TEntity 的基础类型,而不是任何其他通用 类 或它将实现的接口。因此,在下面的示例中,希望 return 类型应该是 Thing<Entity> 而不是 Thing<GenericClass<Entity>>.

扩展方法:

public static Thing<TEntity> DoStuff<TEntity>(IThingRequest<TEntity> request)
    => new Thing<TEntity>();

调用扩展方法:

public class Request : IThingRequest<GenericClass<Entity>>
{ }

var request = new Request();
var result = request.DoStuff();

结果类型现在是 Thing<GenericClass<Entity>>

我的第一直觉是 where 可以实现这一点,但我想不出来。我还考虑过使用反射来获取 TEntity 和 returning Thing<object> 的非泛型类型,但我认为这需要在使用 DoStuff 方法的地方进行强制转换。

非常感谢任何帮助!

如果你想处理嵌套的泛型并且你知道 "wrapper" 一个你需要这样的东西:

public static Thing<T2> UnWrap<T1, T2>(IThingRequest<T1> request) 
       where T1: GenericClass<T2>
=> new Thing<T2>();

我看到以下解决方案变体。 GenericClass 应该实现 IThingRequest。然后可以使 DoStuff 扩展方法反射递归:

using System;
using System.Reflection;

namespace ConsoleApp1
{
    static class Program
    {
        static void Main(string[] args)
        {
            var request = new Request();
            var result = request.DoStuff();
            Console.ReadKey();
        }

        private static MethodInfo _doStaffMethodInfo;
        public static MethodInfo DoStaffMethodInfo => _doStaffMethodInfo = _doStaffMethodInfo ?? typeof(Program).GetMethod("DoStuff");

        public static object DoStuff<TEntity>(this IThingRequest<TEntity> request)
        {
            Type underlyingTypeOfTEntity = typeof(TEntity).GetInterface("IThingRequest`1")?.GenericTypeArguments[0];
            if (underlyingTypeOfTEntity != null)
            {
                MethodInfo doStaffMethodInfo = DoStaffMethodInfo.MakeGenericMethod(underlyingTypeOfTEntity);
                object thingRequest = Activator.CreateInstance(typeof(ThingRequest<>).MakeGenericType(underlyingTypeOfTEntity));
                return doStaffMethodInfo.Invoke(null, new []{thingRequest});
            }
            else
            {
                return new Thing<TEntity>();
            }
        }
    }

    public interface IThingRequest<TEntity>
    {

    }

    public class GenericClass<TEntity> : IThingRequest<TEntity>
    {
    }

    public class Thing<TEntity>
    {
    }

    public class ThingRequest<TEntity> : IThingRequest<TEntity>
    {

    }

    public class Request : IThingRequest<GenericClass<Entity>>
    { }

    public class Entity
    {
    }
}

感谢所有的输入!

我想要一个不需要将 DoStuff 的结果转换为 Thing<TEntity> 的解决方案,例如转换 object。多亏了@Charleh,我才意识到我处理问题的方式是错误的,解决方案就是像这样分别实现 class 和接口:

public class Request : GenericClass<TEntity>, IThingRequest<Entity>
{ }