У меня есть список объектов, на которых мне нужно выполнить функцию Distinct(). В настоящее время я использую следующий код.
Return choices = displaylist
.Select(Function(x) x.Zone)
.ToList
.Distinct()
Вышеприведенный код хорошо работает для меня. Однако мне нужно развернуть этот код во что-то, что позволяет мне указать любое имя свойства и вернуть мне различные значения списка. Мой пользовательский объект имеет свойства 20+, например Zone, Region, Department и т.д.
Мне нужно сделать гибкую функцию, которую я даю любому имени свойства, и он возвращает разные. Что-то вроде этого псевдо:
Function GetDistincts(PROPERTYNAME as string)
Return choices = displaylist
.Select(Function(x) x.[PROPERTYNAME])
.ToList
.Distinct()
End Function
Я считаю, что это работа для Linq Expressions. Но я не гожусь. Так что нужна помощь здесь.
Благодарю!
Вы можете использовать возможности методов расширения и общих типов для написания общего метода расширения для получения отличного результата из каждого списка (Of T):
VB
Dim objects = New List(Of TestObject)()
objects.Add(New TestObject(1, "Test1"))
objects.Add(New TestObject(1, "Test2"))
objects.Add(New TestObject(1, "Test3"))
objects.Add(New TestObject(2, "Test4"))
objects.Add(New TestObject(2, "Test5"))
objects.Add(New TestObject(2, "Test6"))
Dim t As List(Of Integer) = objects.GetDistict(Of Integer, TestObject)("Zone")
Public Class TestObject
Public Property Zone As Integer
Public Property Address As String
Public Sub New(z As Integer, a As String)
Zone = z
Address = a
End Sub
End Class
Public NotInheritable Class DistinctExtension
Private Sub New()
End Sub
<System.Runtime.CompilerServices.Extension> _
Public Shared Function GetDistict(Of T, S)(source As List(Of S), name As String) As List(Of T)
Return source.[Select](Function(x) DirectCast(x.[GetType]().GetProperty(name).GetValue(x), T)).Distinct().ToList()
End Function
End Class
С#
var objects = new List<TestObject>();
objects.Add(new TestObject(1,"Test1"));
objects.Add(new TestObject(1,"Test2"));
objects.Add(new TestObject(1,"Test3"));
objects.Add(new TestObject(2,"Test4"));
objects.Add(new TestObject(2,"Test5"));
objects.Add(new TestObject(2,"Test6"));
List<int> t = objects.GetDistict<int, TestObject>("Zone");
public static class DistinctExtension
{
public static List<T> GetDistict<T,S>(this List<S> source, string name)
{
return source.Select(x => (T)x.GetType().GetProperty(name).GetValue(x)).Distinct().ToList();
}
}
public class TestObject
{
public int Zone { get; set; }
public string Address { get; set; }
public TestObject(int zone, string address)
{
Zone = zone;
Address = address;
}
}
Вы можете создать собственный универсальный метод расширения. Также обратите внимание, что перед вызовом ToList вы должны вызывать разные символы, так как это скомпилирует выражение; делая запрос менее эффективным.
Dim result = displaylist.Property("Zone").Distinct().ToList()
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Public Module Extensions
<Extension()>
Public Function [Property](Of TSource)(source As IEnumerable(Of TSource), name As String) As IEnumerable(Of Object)
Dim descriptor As PropertyDescriptor = TypeDescriptor.GetProperties(GetType(TSource)).Find(name, True)
Return source.Select(Function(item As TSource) descriptor.GetValue(item))
End Function
<Extension()>
Public Function [Property](Of TSource, TResult)(source As IEnumerable(Of TSource), name As String) As IEnumerable(Of TResult)
Dim descriptor As PropertyDescriptor = TypeDescriptor.GetProperties(GetType(TSource)).Find(name, True)
Return source.Select(Function(item As TSource) CType(descriptor.GetValue(item), TResult))
End Function
End Module
Краткий способ ответить на ваш вопрос - использовать блестящее расширение Dynamic LinQ для записи:
С#
используя System.Linq; используя System.Linq.Dynamic;
string Полеvalue = "Зона";
Список <строка> Выбор = Список отображения.Выберите (Имя поля).Cast <string>().Distinct().ToList();