C# 如何在上下文中动态地为方法指定泛型类型(如果可能的话,没有反射)
那么,是否可以在C#中为方法动态指定泛型类型?我说的不是使用反射,而是使用C 例如:C# 如何在上下文中动态地为方法指定泛型类型(如果可能的话,没有反射),c#,generics,reflection,C#,Generics,Reflection,那么,是否可以在C#中为方法动态指定泛型类型?我说的不是使用反射,而是使用C 例如: internal class MyRepository { async Task<IEnumerable<WhateverClass>> GetItemsFor<T>(int entityId, int itemId, params string[] keys) where T : class, IEntity { // do whatever }
internal class MyRepository
{
async Task<IEnumerable<WhateverClass>> GetItemsFor<T>(int entityId, int itemId, params string[] keys)
where T : class, IEntity
{
// do whatever
}
}
interface IEntity
{
public int Id { get; set; }
}
internal class Foo : IEntity
{
// whatever
}
因为泛型T
正在访问T
类型的DbSet
,所以我需要能够在上下文中提供这一点
那么我该如何解决这个难题呢?反思是不被禁止的,但我想知道是否有一种“本土”的方式。或者是一种值得尊敬的思考方式
编辑1:
WhateverClass
与entity
相关。假设我想根据IEntity
是否在集合中设置bool
。这被抽象了很多,但是在这里键入所有上下文是没有用的
public class WhateverClass
{
public bool Enabled { get; set }
}
不,没有思考,这是不可能的。您需要使用反射来获取要调用的泛型方法的MethodInfo,然后使用.MakeGenericMethod()调用来应用“foo”类型并使用.Invoke()调用它 另外,这是返回一个枚举,具体是什么?如果foo是内部的,那么消费者会期望什么
我还认为您所做的完全违反了您所使用的存储库模式。使用者不需要知道它可以传递给方法的类型。存储库应该用于特定的数据集。不,如果没有反射,这是不可能的。您需要使用反射来获取要调用的泛型方法的MethodInfo,然后使用.MakeGenericMethod()调用来应用“foo”类型并使用.Invoke()调用它 另外,这是返回一个枚举,具体是什么?如果foo是内部的,那么消费者会期望什么
我还认为您所做的完全违反了您所使用的存储库模式。使用者不需要知道它可以传递给方法的类型。存储库应该用于特定的数据集。一个选项是使用从开关表达式调用的通用方法。为了简洁起见,可以使用嵌套方法。这样既可以避免重复,也可以避免反思。例如:
getItems的公共任务(
字符串,int-entityId,int-itemId,params字符串[]键)
{
回位串开关
{
“foo”=>Impl(),
“bar”=>Impl(),
_=>抛出新的ArgumentException($“Unknown”for“value:{forAsString}”);
};
异步任务Impl()=>
wait_myRepository.GetItemsFor(entityId、itemId、Key);
}
您仍然需要开关表达式,但它可能比使用反射更好。一个选项是使用从开关表达式调用的通用方法。为了简洁起见,可以使用嵌套方法。这样既可以避免重复,也可以避免反思。例如:
getItems的公共任务(
字符串,int-entityId,int-itemId,params字符串[]键)
{
回位串开关
{
“foo”=>Impl(),
“bar”=>Impl(),
_=>抛出新的ArgumentException($“Unknown”for“value:{forAsString}”);
};
异步任务Impl()=>
wait_myRepository.GetItemsFor(entityId、itemId、Key);
}
您仍然需要switch表达式,但它可能比使用反射更好。这里什么是
WhateverClass
?这是否也取决于的?(如果以“foo”作为第一个参数调用,您是否希望它返回一个任务
?@jonsket no whates是一个与IEntity
相关的公共类。但是因为Foo
是内部的,我不能返回IEnumerable
,因为这是不允许的everclass
与“Foo”有什么关系?@Llama我认为这对这个问题不重要。在我的编辑中,我解释了这一点。@Llama是的,我不是唯一一个在这个项目上工作的人,很不幸,重构不会发生。如果这是我的个人项目,它会被创建得有点不同。所以问题是,“什么是值得尊敬的反射方式”这里什么是WhateverClass
?这是否也取决于
的?(如果以“foo”作为第一个参数调用,您是否希望它返回一个任务
?@jonsket no whates是一个与IEntity
相关的公共类。但是因为Foo
是内部的,我不能返回IEnumerable
,因为这是不允许的everclass
与“Foo”有什么关系?@Llama我认为这对这个问题不重要。在我的编辑中,我解释了这一点。@Llama是的,我不是唯一一个在这个项目上工作的人,很不幸,重构不会发生。如果这是我的个人项目,它会被创建得有点不同。所以问题是,“什么是值得尊敬的反射方式”编辑了我的问题我的存储库是针对特定的数据集的。这种方法适用于我们数据库的高级过滤系统,其中过滤器可以应用于实体集合。谜题的最后一步是从我们的CMS链接到必须应用的实际过滤器。因为我们的数据层是内部的,所以我必须使用DTO。但我确实需要知道我得到的过滤器是针对哪个特定的IEntity
。这就是T
编辑的内容我的问题我的存储库是针对特定数据集的。这种方法适用于我们数据库的高级过滤系统,其中过滤器可以应用于实体集合。谜题的最后一步是从我们的CMS链接到必须应用的实际过滤器。因为我们的数据层是内部的,所以我必须使用DTO。但我确实需要知道我得到的过滤器是针对哪个特定的IEntity
。这就是T
的作用,我喜欢你的方法,但不会像你键入的那样工作。我采纳了你的想法,得到了一个有效的版本。需要将开关的输出存储在<代码中
public class WhateverClass
{
public bool Enabled { get; set }
}