如何使用Linq / Lambda过滤List <object>

时间:2016-05-10 17:57:34

标签: c# linq list object filter

这是我的方案

List<object>

如何过滤obj.Where(t => t.name == "Jakob")这样的内容,以便返回名为“Jakob”的用户列表?

public class NetworkReceiver extends BroadcastReceiver { private static final String TAG = NetworkReceiver.class.getSimpleName(); private static final List<NetworkStatusObserver> mObserverList = new ArrayList<>(); private static boolean isNetworkConnected = true; @Override public void onReceive(Context context, Intent intent) { Logger.i(TAG, "onReceive() broadcast"); boolean disconnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); boolean isNetworkConnectedCurrent; if (disconnected) { isNetworkConnectedCurrent = false; } else { NetworkInfo networkInfo; if (Build.VERSION.SDK_INT < 17) { networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); } else { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); networkInfo = cm.getActiveNetworkInfo(); } isNetworkConnectedCurrent = !FrameworkUtils.checkIfNull(networkInfo) && networkInfo.isConnectedOrConnecting(); } if (isNetworkConnectedCurrent != isNetworkConnected) { isNetworkConnected = isNetworkConnectedCurrent; Logger.d(TAG, "NetworkStatus.onReceive - isNetworkConnected: " + isNetworkConnected); notifyObservers(isNetworkConnected); } } /** * Lets all {@link NetworkStatusObserver}s know if the DEVICE is connected to a network. * * @param isNetworkConnectedCurrent */ private void notifyObservers(Boolean isNetworkConnectedCurrent) { for (NetworkStatusObserver networkStatusObserver : mObserverList) { networkStatusObserver.notifyConnectionChange(isNetworkConnectedCurrent); } } /** * Add observer to observer list * * @param observer */ public void addObserver(NetworkStatusObserver observer) { mObserverList.add(observer); } /** * Remove observer from observer list * * @param observer */ public void removeObserver(NetworkStatusObserver observer) { mObserverList.remove(observer); } /** * Retrieve observer list size * * @return */ public int getObserverSize() { return mObserverList.size(); } /** * Check if receiver is added to observer list * * @param observer * @return */ public boolean contains(NetworkStatusObserver observer) { return mObserverList.contains(observer); } /** * Method is used to print observer list */ public void printObserverList() { Logger.i(TAG, "===== PRINT OBSERVER LIST ===== "); for (int i = 0; i < mObserverList.size(); i++) { Logger.i(TAG, String.format("item(%d): %s", i, mObserverList.get(i).toString())); } } /** * Interface for monitoring network status change */ public interface NetworkStatusObserver { void notifyConnectionChange(boolean isConnected); } } 不起作用

4 个答案:

答案 0 :(得分:4)

如果您将对象转换为动态,它应该可以工作:

obj.Where(t => ((dynamic)t).name == "Jakob")

修改

为了完整起见,我应该提几件事:

  • 动态类型的使用归结为使用带有反射的对象,因此如果使用此方法,最终你不会得到比反射更好的东西。
  • 动态的使用包括将必要的程序集(例如,DLR)加载到CLR中,如果您根本不使用动态,则无法加载。换句话说,这是一个开销。

因此,请自行决定使用。

答案 1 :(得分:4)

您拥有的最佳选择是声明代表用户的类。

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

然后创建User个对象列表并查询此列表。

var users = new List<User>
{
    new User { Id = 1,  Name = "Jakob" },
    new User { Id = 2,  Name = "Sam" },
    new User { Id = 3,  Name = "Albert" }
}

var filteredUsers = users.Where(user => user.Name == "Jakob");

否则,你必须依靠Tengiz建议的解决方案。

答案 2 :(得分:0)

另一种方法是创建匿名类型数组,然后通过ToList IEnumerable扩展方法将其转换为列表:

var obj = (new[] {
    new { id = 1, name = "Jakob" },
    new { id = 2, name = "Sam" },
    new { id = 3, name = "Albert" },
    new { id = 1, name = "Jakob" }}).ToList();
obj.Where(c => c.name == "Jakob");

如果你真的不需要列表,阵列也很好 - 只是不要转换为列表。好处是您有强类型列表而不是任意对象列表。

答案 3 :(得分:-1)

你可以使用反射

    var l = new List<object>();
    l.Add(new {key = "key1", v = "value1"});
    l.Add(new {key = "key2", v = "value2", v2="another value"});
    l.Add(new {key = "key3", v = "value3", v3= 4});
    l.Add(new {key = "key4", v = "value4", v4 = 5.3});

    var r = l.Where(x=> (string)x.GetType().GetProperty("key")?.GetValue(x) == "key1");

获取元素的类型并找到您要查找的属性。然后获取当前实例的值,并将其与要筛选的值进行比较。

但另一方面,即使List包含几种不同匿名类型的项(如果它们具有不同的属性),这种方法也具有工作的优势,只要它们都具有您要过滤的属性。

修改

使用c#6,您可以使用?运算符,这是一种内联检查null。即,如果GetProperty()返回null因为找不到属性,则表达式返回null而不执行GetValue()(否则会抛出NullReferenceException