Ph0*_*n1x 1 c# generics inheritance
是否可以在C#中创建通用限制,使用where仅选择具有某个名称的Field的类.
例如,我AbstractService<T>
有一个方法IEnumerable<T> ProvideData(userId);
在内部提供数据我应该只选择具有相同用户bla-bla-bla.Where的实例(d => d.UserId == userId).但是d.UserId无法解决.怎么可能解决这个问题?
重要提示:我无法从具有UserID字段的类或接口继承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
{
}
Run Code Online (Sandbox Code Playgroud)
[编辑]当你编辑你的问题时,你不能改变类来实现一个接口,这里有一些选择,但没有一个依赖于泛型约束:
代码:
public class SomeClass<T>{
public SomeClass<T>()
{
var tType = typeof(T);
if(tType.GetProperty("UserId") == null) throw new InvalidOperationException();
}
}
Run Code Online (Sandbox Code Playgroud)
代码:
public class SomeClass<T>{
[ContractInvariantMethod]
private void THaveUserID()
{
Contract.Invariant(typeof(T).GetProperty("UserId") != null);
}
}
Run Code Online (Sandbox Code Playgroud)
如果生成了源类,则可以作弊.我使用这种技术,有许多Web引用具有相同类型的参数对象
想象一下,Web引用产生了这个代理代码:
namespace WebServiceA {
public class ClassA {
public int UserId { get; set; }
}
}
namespace WebServiceB {
public partial class ClassB {
public int UserId { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在自己的代码中使用它们来包装它们:
public interface IWithUserId
{
public int UserId { get; set; }
}
public partial class ClassA : IWithUserId
{
}
public partial class ClassB : IWithUserId
{
}
Run Code Online (Sandbox Code Playgroud)
然后,对于您的服务,您可以为几个Web服务的任何类实例化AbstractService:
public class AbstractService<T> where T : IWithUserId
{
}
Run Code Online (Sandbox Code Playgroud)
这种技术很有效,但只有在因为partial关键字技巧而可以在同一个项目中扩展类时才适用.
| 归档时间: |
|
| 查看次数: |
511 次 |
| 最近记录: |