2009-08-25 146 views
43

我知道我不能写这样的方法:有没有办法从方法返回匿名类型?

public var MyMethod() 
{ 
    return new{ Property1 = "test", Property2="test"}; 
} 

我能做到这一点,否则:

public object MyMethod() 
{ 
    return new{ Property1 = "test", Property2="test"} 
} 

,但我不希望,因为如果我这样做的做的第二个选项,我将不得不使用反思。


我为什么要这么做:

今天我在我的aspx页面的方法返回DataTable的结果,我不能改变它,我想这个数据表转换为具有我想要使用的属性的匿名方法。我不想创建一个类来做到这一点,因为我将需要多次执行相同的查询,我认为创建一个返回匿名类型的方法将是一个很好的理想。

+0

你会用它做什么?你如何得出结论,你会想要做那样的事情? – Guffa 2009-08-25 17:26:00

+0

@Guffa,我有一个方法在我的aspx页面返回一个datatable作为结果,我试图将这个数据表转换为一个匿名方法与我想要使用的属性。我不想创建一个类来做到这一点,因为我需要多次执行相同的查询,所以我创建一个返回匿名方法的方法将是一个好的理念。 – Cleiton 2009-08-25 17:33:10

+1

@Cleiton - 创建一个包含数据的类将花费更少的精力。我意识到,仅仅因为我可以使用匿名类型轻松操作数据,并不意味着我需要停止创建类来定义这些类型,因为我需要将它们从一个层传递到另一个层。 – Jagd 2009-08-25 17:38:42

回答

57

将其返回为System.Object只有方法从方法返回匿名类型。不幸的是,没有其他方法可以做到这一点,因为匿名类型是专门设计的,以防止它们以这种方式使用。

有一些技巧,你可以做与结合返回Object,让你接近。如果您对此解决方案感兴趣,请阅读Can't return anonymous type from method? Really?

免责声明:即使我链接的文章确实显示了一种解决方法,并不意味着这是一个好主意。我强烈建议您在创建常规类型时使用此方法更安全,更易于理解。

+10

应该指出,这不是一个推荐的想法。 Intellisense将不再识别匿名类型的强类型属性(您的示例中为Property1和Property2)。实际上,你可以使用反射来获得属性,但是你也可以用锤子敲击你的所有工作,更不用说你只是采取了一些让你的生活更轻松的事情,但事实上让它更难。 – Jagd 2009-08-25 17:29:10

+0

+1本人无法说得更好。是的,它可以完成,但这并不意味着它是一个好主意。 – 2009-08-25 17:30:40

+0

它可以完成! _这只是一个p.i.t.a._ – 2014-02-17 15:47:16

1

不,匿名类型不能存在于创建它们的上下文之外,因此不能用作方法的返回类型。您可以将实例作为object返回,但为此目的明确创建自己的容器类型更好。

0

对不起,你真的不应该这样做。你可以用反射或通过使用泛型辅助方法来为你返回类型,但这样做实际上与语言相反。只需声明该类型即可清楚发生了什么。

2

我想Andrew Hare是对的,你只需要返回“对象”。对于编辑评论,我觉得在OO代码中处理原始对象可能是一种“代码味道”。有些情况下是正确的,但大多数情况下,如果要返回相关类型,最好定义要返回的接口或使用某种基类类型。

1

不,不支持在方法之外扩展匿名类的范围。除了方法之外,类是真正匿名的,反射是访问其成员的唯一方法。

13

最简单的解决方案是创建一个类,将值移入属性中,然后将其返回。如果匿名类型让你的生活更难,那么你没有正确使用它们。

13
public object MyMethod() 
{ 
    return new 
    { 
     Property1 = "test", 
     Property2 = "test" 
    }; 
} 

static void Main(..) 
{ 
    dynamic o = MyMethod(); 
    var p1 = o.Property1; 
    var p2 = o.Property2; 
} 
21

或者,您可以使用.NET 4中的Tuple类。0和更高:

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

Tuple<string, string> Create() 
{ 
return Tuple.Create("test1", "test2"); 
} 

那么你就可以访问属性是这样的:

var result = Create(); 
result.Item1; 
result.Item2; 
+8

好笑。我来到这里寻找使用元组作为返回类型的替代方法。 – SixOThree 2015-05-28 19:58:27

6

尽管有关这是否是一个好主意或不警告...一个dynamic似乎为私人方法工作得很好。

private dynamic MyMethod() 
{ 
    return new { Property1 = "test", Property2 = "test" } 
} 
+0

我认为这不是最好的,因为动态会构建到每个数据类型中,包括对象,所以您会更好地使用对象,而且开销更少。 – MrKekson 2016-09-28 15:44:34