C# 有没有办法从方法返回匿名类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1329672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:12:39  来源:igfitidea点击:

Is there a way to return Anonymous Type from method?

c#.netanonymous-types

提问by Cleiton

I know I can't write a method like:

我知道我不能写这样的方法:

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

I can do it otherwise:

我可以这样做:

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

but I don't want to do the second option because, if I do so, I will have to use reflection.

但我不想做第二个选项,因为如果我这样做,我将不得不使用反射。



Why I want to do that:

我为什么要这样做:

Today i have a method inside my aspx page that returns a datatable as result and I cannot change it, I was trying to convert this DataTable to an Anonymous method with the properties that I want to work with. I didn't want to create a class only to do that and as I will need to perform the same query more than one time, I Thought to create a method that returns an anonymous type would be a good ideia.

今天,我的 aspx 页面中有一个方法,它返回一个数据表作为结果,我无法更改它,我试图将此数据表转换为具有我想要使用的属性的匿名方法。我不想创建一个类只是为了做到这一点,因为我需要多次执行相同的查询,我认为创建一个返回匿名类型的方法将是一个好主意。

采纳答案by Andrew Hare

Returning it as a System.Objectis the onlyway to return an anonymous type from a method. Unfortunately there is no other way to do this since anonymous types were designed specifically to prevent their use in this way.

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

There are some tricks that you can do to in conjunction with returning an Objectthat allow you to get close. If you are interested in this workaround please read Can't return anonymous type from method? Really?.

有一些技巧可以与返回Object允许您接近的方法结合使用。如果您对此解决方法感兴趣,请阅读无法从方法返回匿名类型?真的吗?.

Disclaimer:Even though the article I linked does show a workaround that doesn't mean it is a good idea to do it. I would strongly discourage you using this approach when creating a regular type would be safer and easier to understand.

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

回答by Adam Robinson

No, anonymous types cannot exist outside of the context in which they are created, and as a result cannot be used as a method return type. You can return the instance as an object, but it's a much better idea to explicitly create your own container type for this purpose.

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

回答by mqp

Sorry, you really aren't supposed to do that. You can hack around it with reflection or by making a generic helper method to return the type for you, but doing so is really working against the language. Just declare the type so it's clear what's going on.

对不起,你真的不应该那样做。您可以通过反射或通过创建一个通用的辅助方法来为您返回类型来绕过它,但这样做确实不利于该语言。只需声明类型,以便清楚发生了什么。

回答by Andy White

I think Andrew Hare is right, you'd have to just return "object." For an editorial comment, I feel like dealing with raw objects in OO code can be a "code smell." There are cases where it's the right thing to do, but most of the time, you'd be better off defining an interface to return, or using some sort of base class type, if you're going to be returning related types.

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

回答by Guffa

No, there is no support for expanding the scope of the anonymous class outside the method. Outside of the method the class is truly anonymous, and reflection is the only way to access it's members.

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

回答by Jagd

The easiest solution is to create a class, shove the values into the property, and then return it. If anonymous types are making your life harder then you're not using them correctly.

最简单的解决方案是创建一个类,将值推送到属性中,然后返回它。如果匿名类型让您的生活变得更加艰难,那么您就没有正确使用它们。

回答by Nana Kofi

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

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

回答by The Light

Alternatively, you can use the Tuple class in .NET 4.0 and higher:

或者,您可以在 .NET 4.0 及更高版本中使用 Tuple 类:

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

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

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

then you can access the properties like this:

然后你可以访问这样的属性:

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

回答by controlbox

Notwithstanding the warnings about whether this is a good idea or not... A dynamicseems to work just fine for a private method.

尽管有关于这是否是一个好主意的警告...... Adynamic对于私有方法似乎工作得很好。

void Main()
{
    var result = MyMethod();
    Console.WriteLine($"Result: {result.Property1}, {result.Property2}");
}

public dynamic MyMethod()
{
    return new { Property1 = "test1", Property2 = "test2" };
}

You can run this example in LinqPad.It will output:

您可以在LinqPad 中运行此示例它会输出:

Result: test1, test2

结果:测试1,测试2

回答by sneusse

You could also invert your control flow if possible:

如果可能,您还可以反转控制流:

    public abstract class SafeAnon<TContext>
    {
        public static Anon<T> Create<T>(Func<T> anonFactory)
        {
            return new Anon<T>(anonFactory());
        }

        public abstract void Fire(TContext context);
        public class Anon<T> : SafeAnon<TContext>
        {
            private readonly T _out;

            public delegate void Delayed(TContext context, T anon);

            public Anon(T @out)
            {
                _out = @out;
            }

            public event Delayed UseMe;
            public override void Fire(TContext context)
            {
                UseMe?.Invoke(context, _out);
            }
        }
    }

    public static SafeAnon<SomeContext> Test()
    {
        var sa = SafeAnon<SomeContext>.Create(() => new { AnonStuff = "asdf123" });

        sa.UseMe += (ctx, anon) =>
        {
            ctx.Stuff.Add(anon.AnonStuff);
        };

        return sa;
    }

    public class SomeContext
    {
        public List<string> Stuff = new List<string>();
    }

and then later somwhere else:

然后在其他地方:

    static void Main()
    {
        var anonWithoutContext = Test();

        var nowTheresMyContext = new SomeContext();
        anonWithoutContext.Fire(nowTheresMyContext);

        Console.WriteLine(nowTheresMyContext.Stuff[0]);

    }