类字段限制的泛型
本文关键字:泛型 字段 | 更新日期: 2023-09-27 18:17:06
是否有可能在c#中创建通用限制,使用只选择具有某些名称的字段的类?
例如,我有AbstractService<T>
我有一个方法IEnumerable<T> ProvideData(userId)
;
在提供数据中,我应该只选择具有相同用户的实例等等等等。其中(d => d. userId == userId)。但是d.UserId无法解析。如何解决这个问题?
重要:我不能从类或接口继承T,它们有UserID字段
你正在寻找的是一个接口:
public interface IWithSomeField
{
int UserId { get; set; }
}
public class SomeGenericClasss<T>
: where T : IWithSomeField
{
}
public class ClassA : IWithSomeField // Can be used in SomeGenericClass
{
int UserId { get; set; }
}
public class ClassB // Can't be used in SomeGenericClass
{
}
[Edit]当你编辑你的问题时,你不能改变类来实现一个接口,这里有一些替代方案,但没有一个依赖于泛型约束:
- 检查构造函数中的类型:
public class SomeClass<T>{
public SomeClass<T>()
{
var tType = typeof(T);
if(tType.GetProperty("UserId") == null) throw new InvalidOperationException();
}
}
- 使用代码契约不变量(不确定语法):
public class SomeClass<T>{
[ContractInvariantMethod]
private void THaveUserID()
{
Contract.Invariant(typeof(T).GetProperty("UserId") != null);
}
}
- 用部分类扩展现有类
如果生成了源类,可以作弊。我对许多具有相同类型参数对象的Web引用使用了这种技术
想象Web引用产生了以下代理代码:
namespace WebServiceA {
public class ClassA {
public int UserId { get; set; }
}
}
namespace WebServiceB {
public partial class ClassB {
public int UserId { get; set; }
}
}
您可以在自己的代码中使用:
public interface IWithUserId
{
public int UserId { get; set; }
}
public partial class ClassA : IWithUserId
{
}
public partial class ClassB : IWithUserId
{
}
然后,对于您的服务,您可以为几个web服务中的任何一个类实例化AbstractService:
public class AbstractService<T> where T : IWithUserId
{
}
这项技术非常有效,但仅适用于由于部分关键字技巧而可以在同一项目中扩展class的情况。