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>
{ }
我正在尝试编写 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>
{ }