在C#中将匿名对象作为参数传递

18

我在一个方法的参数中无法传递匿名对象,我想像 JavaScript 中那样传递这个对象。例如:


I have a problem with passing an anonymous object as an argument in a method. I want to pass the object like in JavaScript. Example:
function Test(obj) {
    return obj.txt;
}
console.log(Test({ txt: "test"}));

但是在 C# 中,它会抛出很多异常:

class Test
{
    public static string TestMethod(IEnumerable<dynamic> obj)
    {
        return obj.txt;
    }
}
Console.WriteLine(Test.TestMethod(new { txt = "test" }));

异常:

  1. 第1个参数:无法将“AnonymousType#1”转换为“System.Collections.Generic.IEnumerable”
  2. 最佳重载方法匹配“ConsoleApplication1.Test.TestMethod(System.Collections.Generic.IEnumerable)”的一些无效参数
  3. “System.Collections.Generic.IEnumerable”不包含名为“txt”的定义,也没有接受类型为“System.Collections.Generic.IEnumerable”的第一个参数的扩展方法“txt”可以找到(您是否缺少使用指令或程序集引用 ?)

2
为什么要将匿名对象传递给需要IEnumerable的方法?让它接受'dynamic'就可以了。 - GregRos
@GregRos 谢谢,我是新手强类型语言,我的研究告诉我这个... - user1091156
3个回答

36

看起来你想要:

class Test
{
    public static string TestMethod(dynamic obj)
    {
        return obj.txt;
    }
}

你将其用作单个值,而不是序列。你真的想要一个序列吗?


13

这应该就可以了...

class Program
{
    static void Main(string[] args)
    {
        var test = new { Text = "test", Slab = "slab"};
        Console.WriteLine(test.Text); //outputs test
        Console.WriteLine(TestMethod(test));  //outputs test
    }

    static string TestMethod(dynamic obj)
    {
        return obj.Text;
    }
}

3
这很好运行:)
public class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine(Test.TestMethod(new[] {new {txt = "test"}}));
        Console.ReadLine();
    }
}

public class Test
{
    public static string TestMethod(IEnumerable<dynamic> obj)
    {
        return obj.Select(o => o.txt).FirstOrDefault();
    }
}

谢谢,非常完美。我只是惊讶于写一件事情有这么多选择 :) - user1091156
如果你只是要获取第一个项目,为什么一开始就要使用可枚举对象呢? - Servy
@Servy 我只是一个观察者,现在偶然发现这个问题,但这只是一个测试;它并不重要。我认为使用IEnumerable进行测试很好,因为它证明了使用new[] { new {..}}的语法约定,这通常是匿名对象传递集合的方式。事实上,这正是我需要看到的;我将其用作“params”参数。 - Jon Davis
@stimpy77 我看到这个问题有两种解决方案。1.将参数更改为单个值,因为很明显(在他提问后表明了这一点),这就是OP真正想要的。2.取一个项目的IEnumerable并对所有项目执行操作。如果他只是返回了所有字符串的序列,或者对所有字符串做了些什么,那么这是合适的。我猜你不只是在.FirstOrDefault中使用你的params列表,是吗? - Servy
我同意,如果你只打算取第一个值,那么在第一位放一个IEnumerable参数是没有必要的。由于OP目前显示了IEnumerable输入和单个输出,我只是建议即使测试看起来很荒谬,也可以证明如果你把它这样使用,仍然可以获取数据。争议在于Javascript哈希表(就像OP的第一个示例中)是可枚举的。但在C#中等价于对象的多个成员;动态对象具有成员,它们可以被枚举。因此你是对的,IEnumerable不对;动态足够了。 - Jon Davis
我的 TestMethod 实现只是一个示例,正如您所指出的,它没有太多意义。我不知道 user1091156 真正想要做什么。他还可能需要在 TestMethod 中添加一些逻辑。 - Rookian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接