首页 > 解决方案 > 如何使用通用类型运行 LINQ 查询

问题描述

这是我的类,基本上是封闭耦合类型我想概括这个类。

所以我可以与所有班级一起使用

调用此方法时会有一个 Name 字段是很常见的

    public class CustomSuggestionProvider : ISuggestionProvider
    {
        private const int batchSize = 30;
        private string _criteria = string.Empty;
        private int _skipCount;

        private readonly ObservableCollection<LanguageItem> _observableCollection;
        private readonly List<LanguageItem> _source;

        public CustomSuggestionProvider(ObservableCollection<LanguageItem> observableCollection, List<LanguageItem> source)
        {
            _observableCollection = observableCollection;
            _source = source;
        }

        public bool HasMoreSuggestions { get; private set; } = true;

        public Task<IList<object>> GetSuggestionsAsync(string criteria, CancellationToken cancellationToken)
        {
            _criteria = criteria;
            var newItems = _source.Where(x => x.Name.IndexOf(_criteria, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            if (cancellationToken.IsCancellationRequested)
                return null;
            HasMoreSuggestions = newItems.Count > batchSize;
            _skipCount = batchSize;
            return Task.FromResult<IList<object>>(newItems.Take(batchSize).Cast<object>().ToList());
        }

     
    }

我只是把它概括成这样。

使所有紧密耦合的类成为 T 型。

请看一看。

 public class CustomSuggestionProvider<T> :  ISuggestionProvider
    {
        private const int batchSize = 30;
        private string _criteria = string.Empty;
        private int _skipCount;
        
        private readonly ObservableCollection<T> _observableCollection;
        private readonly List<T> _source;

        public CustomSuggestionProvider(ObservableCollection<T> observableCollection, List<T> source)
        {
            _observableCollection = observableCollection;
            _source = source;
        }
 

        public bool HasMoreSuggestions { get; private set; } = true;
]


        public Task<IList<object>> GetSuggestionsAsync(string criteria, CancellationToken cancellationToken)
        {
            _criteria = criteria;
                var newItems = _source.Where(x =>Name.IndexOf(_criteria, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            if (cancellationToken.IsCancellationRequested)
                return null;
            HasMoreSuggestions = newItems.Count > batchSize;
            _skipCount = batchSize;
            return Task.FromResult<IList<object>>(newItems.Take(batchSize).Cast<object>().ToList());
        }

        public Task<IList<object>> GetSuggestionsAsync(CancellationToken cancellationToken)
        {
            var newItems = _source.Where(x => x.Name.StartsWith(_criteria)).Skip(_skipCount).ToList();
            if (cancellationToken.IsCancellationRequested)
                return null;
            HasMoreSuggestions = newItems.Count > batchSize;
            _skipCount += batchSize;
            return Task.FromResult<IList<object>>(newItems.Take(batchSize).Where(x => !_observableCollection.Any(y => y.Id == x.Id)).Cast<object>().ToList());
        }
    }

我只是在这个声明中卡住了

此处不存在“名称”

var newItems = _source.Where(x => x.Name.IndexOf(_criteria, StringComparison.OrdinalIgnoreCase) >= 0).ToList();

你能帮忙解决这个问题吗?

提前致谢。

标签: c#wpflinq

解决方案


假设您要使用的每种类型都有一个Name 属性,您只需要一个interface和一个约束

约束通知编译器类型参数必须具有的功能。没有任何约束,类型参数可以是任何类型。编译器只能假定 System.Object 的成员,它是任何 .NET 类型的最终基类。有关详细信息,请参阅为什么使用约束。如果客户端代码使用不满足约束的类型,编译器会发出错误。使用 where 上下文关键字指定约束

给定

public interface IName
{
    public string Name { get; set; }
}

您可以将此接口放在要用作类的泛型参数的每种类型上:

public class Bob : IName
{
   ...
}

例子

然后只需将约束添加到类中where

public class CustomSuggestionProvider<T> :  ISuggestionProvider 
    where T: IName
{

}

请注意,如果您无法约束泛型类型,则可以使用其他选项,根据用例使用Func<T,bool>表达式


推荐阅读