gpt4 book ai didi

c# - 泛型 where 受类字段限制

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:24 25 4
gpt4 key购买 nike

是否可以在 C# 中创建通用限制,使用 where 来仅选择具有某些名称的字段的类。

例如,我有 AbstractService<T>我有一个方法 IEnumerable<T> ProvideData(userId) ;

在里面提供数据我应该只选择具有相同用户 bla-bla-bla.Where(d => d.UserId == userId) 的实例。但无法解析 d.UserId。如何解决这个问题?

重要提示:我无法从具有 UserID 字段的类或接口(interface)继承 T。

最佳答案

界面就是您正在寻找的:

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
{

}

[编辑] 当您编辑您的问题以声明您不能更改类来实现接口(interface)时,这里有一些替代方案,但没有一个依赖于通用约束:

  1. 检查构造函数中的类型:

代码:

public class SomeClass<T>{
public SomeClass<T>()
{
var tType = typeof(T);
if(tType.GetProperty("UserId") == null) throw new InvalidOperationException();
}
}
  1. 使用代码契约不变(不确定语法):

代码:

 public class SomeClass<T>{
[ContractInvariantMethod]
private void THaveUserID()
{
Contract.Invariant(typeof(T).GetProperty("UserId") != null);
}
}
  1. 使用部分类扩展现有类

如果你的源类是生成的,你可以作弊。我将这种技术用于许多具有相同类型参数对象的 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
{
}

此技术非常有效,但仅适用于由于 partial 关键字技巧而可以在同一项目中扩展类的情况。

关于c# - 泛型 where 受类字段限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8414004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com