c# - 如何在上下文中动态指定方法的泛型类型(如果可能,不进行反射)
问题描述
那么是否可以在 C# 中为方法动态指定泛型类型?我不是在谈论使用反射,而是仅使用 C#。
例子:
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
}
现在我的问题是我将提供一个string
“foo”,internal class Foo
因为Foo
它是内部的,我的其他项目无法访问(这是预期的)。但它在外部被称为string
“foo”。
现在我想调用以下方法(这是公共的)。
public async Task<IEnumerable<WhateverClass>> GetItemsFor(string forAsString, int entityId, int itemId, params string[] keys)
{
var forAsType = forAsString switch
{
"foo" => typeof(Foo) // or what is needed here
};
return await _myRepository.GetItemsFor<forAsType>(entityId, itemId, keys); // this is not possible. How can I make this work?
}
因为泛型T
正在访问一个DbSet
类型,T
所以我需要能够在上下文中提供它。
那么我该如何解决这个难题呢?反思是不被禁止的,但我想知道是否有一种“原生”的方式。或者一种体面的反思方式
编辑1:
WhateverClass
与 有相关性IEntity
。假设我想根据 abool
是否IEntity
在集合中来设置 a 。这被抽象了很多,但是在这里键入所有上下文是没有用的。
public class WhateverClass
{
public bool Enabled { get; set }
}
解决方案
一种选择是使用从 switch 表达式调用的通用方法。为简洁起见,这可以是一种嵌套方法。这样可以避免重复,也可以避免反思。例如:
public Task<IEnumerable<WhateverClass>> GetItemsFor(
string forAsString, int entityId, int itemId, params string[] keys)
{
return forAsString switch
{
"foo" => Impl<Foo>(),
"bar" => Impl<Bar>(),
_ => throw new ArgumentException($"Unknown 'for' value: {forAsString}");
};
async Task<IEnumerable<WhateverClass>> Impl<T>() =>
await _myRepository.GetItemsFor<T>(entityId, itemId, keys);
}
您仍然需要 switch 表达式,但它可能比使用反射更好。
推荐阅读
- asynchronous - ASP.NET Core,过度杀伤 Task.Run()?
- node.js - 节点 child_process execSync 与 xclip 一起挂起
- r - R 3.5 包“lattice”由具有不同内部结构的 R 版本安装
- angular - 在 DataTable Angular 中排序格式化日期
- ms-access - 搜索访问多值字段
- git - git:cherry-pick 兄弟提交列表
- r - 在 Xaringan 演示文稿中嵌入 javascript
- validation - 如何为串联的深度 CNN 模型设置验证数据?
- spring-boot - 在 Spring 应用程序上下文中找不到已注册的 RendezvousChannel bean
- c++ - 如何在 C++ Windows 7 下启动/停止 wav 声音