简体   繁体   English

什么是匿名类的返回类型

[英]What's the return type of an anonymous class

I have a class that used to have a string return type. 我有一个曾经有一个字符串返回类型的类。 Now I find I need to return more than a string. 现在我发现我需要返回多个字符串。 I was thinking to return something like below: 我想要返回如下内容:

public string Test()
{
  return ( new { ID = 5, Name= "Dave" } );
}

Is this even possible and if so then what would be the return type? 这是否可能,如果是这样,那么返回类型是什么? I know it's not string .. 我知道这不是字符串..

As others have said, the best thing to do here is to make a nominal type. 正如其他人所说,这里最好的办法就是做一个名义上的类型。 I would suggest that the nominal type have the same characteristics as an anonymous type; 我建议名义类型与匿名类型具有相同的特征; that is, you should consider making the type immutable and consider making it exhibit value equality . 也就是说,您应该考虑使类型不可变,并考虑使其表现出值相等

It is possible to return an anonymous type as object and then use the instance returned elsewhere using a variety of sneaky techniques. 可以返回一个匿名类型的对象,然后使用采用各种卑鄙的技术在其他地方返回的实例。 You can cast the object to "dynamic" (in C# 4) and then use the properties of the anonymous type, but this is slow and lacks compile-time type checking. 您可以将对象转换为“动态”(在C#4中),然后使用匿名类型的属性,但这很慢并且缺少编译时类型检查。

You can also use the "cast by example" trick, which does get you compile-time type checking. 您还可以使用“逐个示例”技巧,它可以让您进行编译时类型检查。 However, that trick only works when the anonymous source object and the anonymous example object come from the same assembly . 但是, 该技巧仅在匿名源对象和匿名示例对象来自同一程序集时才有效

static T CastByExample<T>(object source, T example) where T : class
{
    return source as T;
}

static object ReturnsAnonymous() { return new { X = 123 }; }

static void DoIt()
{
    object obj = ReturnsAnonymous();
    var example = new { X = 0 };
    var anon = CastByExample(obj, example);
    Console.WriteLine(anon.X); // 123
}

See how sneaky that is? 看看这是多么鬼鬼祟祟? We use method type inference and local variable type inference to tell the compiler "these two things are the same type". 我们使用方法类型推断和局部变量类型推断来告诉编译器“这两个东西是同一类型”。 This lets you export an anonymous type as object and cast it back to anonymous type. 这允许您将匿名类型导出为对象并将其强制转换为匿名类型。

But you probably should not do this; 但你可能不应该这样做; if you're resorting to such sneaky tricks then you should simply be defining a nominal type in the first place. 如果你采取这种偷偷摸摸的技巧,那么你应该首先简单地定义名义类型。 Also, like I said, the trick only works if the example and the source objects were created in code in the same assembly; 另外,就像我说的那样,只有在同一个程序集中的代码中创建示例对象时,该技巧才有效; two "identical" anonymous types in two different assemblies do not unify to be the same type. 两个不同程序集中的两个“相同”匿名类型统一为相同类型。

The object that you return does have a class, but it's anonymous so you can't specify it in the code. 您返回的对象确实有一个类,但它是匿名的,因此您无法在代码中指定它。 You just have to return it as an object reference: 您只需将其作为object引用返回:

public object Test() {
  return new { ID = 5, Name= "Dave" };
}

Note that the anonymous type is unknown outside the scope of the method, so reflection is the only way to access its properties. 请注意,匿名类型在方法范围之外是未知的,因此反射是访问其属性的唯一方法。

If you want to be able to use the returned object conveniently, you should declare a class: 如果您希望能够方便地使用返回的对象,则应声明一个类:

public class TestResult
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public TestResult Test() {
    return new TestResult() { ID = 5, Name= "Dave" };
}

Another alternative is to use an existing class, if it fits your purpose. 另一种选择是使用现有的类,如果它符合您的目的。 A KeyValuePair is close to what you use, but then the properties will of course be named Key and Value instead of ID and Name : KeyValuePair接近你使用的,但是属性当然会被命名为KeyValue而不是IDName

public KeyValuePair<int, string> Test() {
  return new KeyValuePair<int, string>(5, "Dave");
}

This isn't possible as the anonymous class is only valid within the current context. 这是不可能的,因为匿名类仅在当前上下文中有效。 If you need to return an object then you'll need to create a real class. 如果你需要返回一个对象,那么你需要创建一个真正的类。

I'm assuming you left string as the return type by accident. 我假设你意外地将string作为返回类型。

Anonymous type are class type that are derived directly from object . Anonymous type是直接从object派生的类类型。

You can return it from method as object as return type. 您可以从方法返回它作为返回类型的object Have a look at this . 看看这个

No, it's not possible. 不,这是不可能的。 Your options are: 你的选择是:

  1. Define a real class for the return value, 为返回值定义一个真实的类,
  2. Use System.Tuple, or 使用System.Tuple,或
  3. Use out parameters (probably the least good option). 使用参数(可能是最不好的选项)。

You can make a struct (or class) for this. 您可以为此创建结构(或类)。

public struct IdAndName
{
    public int Id;
    public string Name;

    public IdAndName(int id, string name)
    {
        ID = id;
        Name = name;
    }
}

You could also use a Tuple<T1, T2>, (but that's not recommended as the properties aren't named. 您也可以使用元组<T1,T2>(但不建议这样做,因为属性未命名。

class NewString
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public NewString Test()
{
    return ( new NewString() { ID = 5, Name = "Dave" } );
}

:) :)

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM