简体   繁体   English

在匿名方法、lambda 表达式、查询表达式或本地 function 中使用的通用参数类型

[英]Generic parameter type to use inside an anonymous method, lambda expression, query expression, or local function

I am new to C# and I am trying to create a method that accept generic parameter type like in Javascript.我是 C# 的新手,我正在尝试创建一个接受通用参数类型的方法,如 Javascript。

Let says I have a List of User objects with name and id properties.假设我有一个具有nameid属性的User对象列表。

In Javascript, to search through the list using property value will be as simple as:在 Javascript 中,使用属性值搜索列表非常简单:

 class User{ constructor(name, id){ this.name = name; this.id = id; } } let users = [ new User("John",1), new User("Deer", 2), new User("Bruce", 3), ] function findArr(arr, propertyName, propertyValue){ for(let a of arr) if(a[propertyName] === propertyValue) return a; return null; } console.log(findArr(users, "name", "Deer")) console.log(findArr(users, "id", 3))

Then, I try to recreate this in C#:然后,我尝试在 C# 中重新创建它:

using System;
using System.Collections.Generic;
using System.Linq;

public class User{
    public string name {get; set;}
    public int id {get; set;}
}

public class HelloWorld
{
    public static void Main(string[] args)
    {
        List<User> Users = new List<User>{
            new User{name="John", id=1},
            new User{name="Deer", id=2},
            new User{name="Bruce", id=3}
        };
        
        int propertyValue = 2;
        var u = FindList<User, int>(Users, "id", ref propertyValue);
        Console.WriteLine(u.name + " " + u.id);
    }
    
    public static T FindList<T, K>(List<T> obj, string propertyName, ref K propertyValue){
        return (T)obj.FirstOrDefault(o=>
                (K)o.GetType().GetProperty(propertyName).GetValue(o, null) 
                == 
                propertyValue
            );
    }
}

But this will throw exception: Cannot use ref, out, or in parameter 'propertyValue' inside an anonymous method, lambda expression, query expression, or local function .但这会抛出异常: Cannot use ref, out, or in parameter 'propertyValue' inside an anonymous method, lambda expression, query expression, or local function

Why is this exception thrown?为什么抛出这个异常?

How do I make this work?我如何使这项工作?

As the error message states, you cannot use the ref or out keywords in an anonymous function. This is by design, as detailed in this answer .如错误消息所述,您不能在匿名 function 中使用 ref 或 out 关键字。这是设计使然,详见此答案

The good news is, you do not need to use ref at all.好消息是,您根本不需要使用 ref。 You can achieve what you want simply by passing the property value as a normal parameter, like so:您只需将属性值作为普通参数传递即可实现您想要的效果,如下所示:

public static T FindList<T, K>(List<T> obj, string propertyName, K propertyValue){
    return (T)obj.FirstOrDefault(o=>
EqualityComparer<K>.Default.Equals((K)o.GetType().GetProperty(propertyName).GetValue(o, null) , propertyValue));
}

Note that the equality check with == operator won't work for unconstrained generic type in general, so we use the EqualityComparer method instead.请注意,== 运算符的相等性检查通常不适用于不受约束的泛型类型,因此我们改用 EqualityComparer 方法。

Javascript is a weakly typed language, every object is essentially just a dictionary. Javascript 是一种弱类型语言,每个 object 本质上只是一个字典。

If you ever find yourself accessing properties by name in C#, you're probably doing something "wrong".如果您发现自己在 C# 中按名称访问属性,您可能做错了什么。

Rather than using reflection, you could pass in a function to access the property;您可以传入 function 来访问该属性,而不是使用反射;

    public static T FindList<T, V>(List<T> obj, Func<T,V> propertyAccess, V propertyValue){
        return obj.FirstOrDefault(o => propertyAccess(o) == propertyValue);
    }

var u = FindList<User, int>(Users, u => u.id, propertyValue);

However, I don't think this method really adds anything to your C# code.但是,我认为这种方法并没有真正为您的 C# 代码添加任何内容。 You'd be better off just writing the straight forward solution, without complicating anything with your own "helper" method;您最好只编写直接的解决方案,而不用您自己的“帮助”方法使任何事情复杂化;

var u = Users.FirstOrDefault(u => u.id == propertyValue);

It's not the same as the javascript code you are familiar with.它与您熟悉的 javascript 代码不同。 But you're writing in C# now.但是你现在正在写 C#。 If you want to work with other C# programmers, you will need to change the way you think about programming problems.如果你想和其他 C# 程序员一起工作,你将需要改变你对编程问题的思考方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为“ in”参数获取“无法在匿名方法,lambda表达式或查询表达式中使用ref或out参数” - Getting “Cannot use ref or out parameter inside an anonymous method, lambda expression, or query expression” for an “in” parameter 如果“错误 CS1628:无法在匿名方法、lambda 或查询表达式中使用 in ref 或 out 参数”,如何在线程中使用 ref 参数? - How to use a ref parameter in a thread if "Error CS1628: Cannot use in ref or out parameter inside an anonymous method, lambda or query expression"? 使用lambda表达式作为泛型类型的参数的构造方法 - Constructor with lambda expression as parameter of generic type 如何将Generic Type参数传递给lambda表达式? - How to pass Generic Type parameter to lambda expression? 以泛型类型输入作为参数的 Lambda 表达式 - Lambda Expression with Generic Type Input as Parameter 用lambda表达式参数调用泛型方法的反射 - Reflection to call generic method with lambda expression parameter 反射:使用泛型参数和lambda表达式作为参数的方法 - Reflection: method with generic argument and lambda expression as parameter lambda表达式内的泛型类型的访问属性 - Access property of a generic type inside lambda expression LINQ:在Where中使用Expression与匿名类型 - LINQ: use Expression inside Where with anonymous type 匿名类型,枚举器和Lambda表达式 - Anonymous Type, Enumerator and Lambda expression
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM