我在 Web API 中有一个抽象的 GetAsync 调用来获取所有类型的类。 (具有类所需的特定代码的实际服务将派生自这个抽象定义)假设我正在使用 Injected MemoryCache 临时替换数据库来测试这个:
public async Task<IEnumerable<T>> GetAsync()
{
if (!memoryCache.TryGetValue(typeof(T).Name, out List<T>? dtoStuff))
{
dtoStuff = new List<T>();
}
return dtoStuff;
}
这非常适合返回任何此类对象的列表。
所有类型的“T”对象都基于相同的接口
public interface ITheObjectInterface
{
}
public class TheObject : ITheObjectInterface
{
...
}
现在,我想通过“id”获取特定项目,并且我知道所有类型的“T”都有一个定义为的成员:
public string? Id { get; set; }
但这不在类所基于的现有 ITheObjectInterface 中。
我的抽象电话是:
public async Task<T> GetAsync(string id)
{
// but how do I access the 'Id' member of any List of type 'T'?
if (!memoryCache.TryGetValue(typeof(T).Name, out List<T>? dtoStuff))
{
dtoStuff = new List<T>();
}
return dtoStuff.FirstOrDefault(o => o.Id== id);
// ^^^^^^^^^^^^^^^^^ error
这可能已经回答了“n”次,但我找不到任何答案......所以只要把我推向正确的方向
如果您不能将
Id
添加到界面,那么我想您可以使用Reflection来获取并设置它。也许你可以在 ITheObjectInterface
: 上写几个扩展方法
static class ExtensionMethods
{
public static string GetId<T>(this T source) where T : ITheObjectInterface
{
return (string)source.GetType().GetProperty("Id")?.GetValue(source);
}
public static void SetId<T>(this T source, string newValue) where T : ITheObjectInterface
{
var property = source.GetType().GetProperty("Id");
if (property == null) throw ArgumentException();
property.SetValue(source, newValue);
}
}
然后你可以这样做:
return dtoStuff.FirstOrDefault(o => o.GetId() == id);