【问题标题】:How to get the value of a property from a function which returns an object?如何从返回对象的函数中获取属性的值?
【发布时间】:2018-06-28 09:37:11
【问题描述】:

我有这个函数返回一个对象:

 private object function1()
 {
   return new
   {
     string1 = "a",
     string2 = "b"
   }
 }

我想将 'string1' 存储到一个变量中。我将如何实现这一目标?这是我尝试过的,但它并没有解决问题:

var a = function1().string1;

【问题讨论】:

  • 您真的不应该返回匿名类型,而是创建一个适当的类并返回它。否则,您必须求助于反射或动态类型,这只是 hacky。

标签: c# function oop object


【解决方案1】:

选项 1 - 正确操作

换句话说,除非你真的不得不

,否则不要使用其他方法

你真的不应该返回匿名类型,正确的做法是创建一个适当的类并返回它。否则,您必须求助于反射或动态类型,这只是 hacky:

类:

public class Foo
{
    public string String1 { get; set; }
    public string String1 { get; set; }
}

方法:

private Foo Function1()
{
    return new Foo
    {
        String1 = "a",
        String2 = "b"
    }
}

用法:

var a = Function1().String1; // Though it's worth checking for a null return in production code

选项 2 - 使用反射

换句话说,请不要这样做

使用你上面的代码,你可以使用反射来获取属性并手动调用它,例如:

var result = function1();

var property = result.GetType().GetProperty("string1");
var a = (string)property.GetValue(result);

选项 3 - 使用动态类型

换句话说,请在上面加糖,不要这样做!

将返回转换为动态,您可以调用任何您喜欢的方法/属性,但这不是类型安全的,如果您调用不存在的方法,则会引发运行时异常。

var result = (dynamic)function1();
var a = (string)result.string1;

【讨论】:

    【解决方案2】:

    我强烈建议使用正确的类定义而不是返回匿名类型

    class MyClass {
        string string1 {get;set;}
        string string2 {get;set;}
    }
    
    
    private MyClass function1() {
        return new MyClass {
           string1 = "a", string2 = "b"
        };
    }
    
    
    Console.WriteLine(function1().string1);
    

    如果你真的想使用匿名类型,你将不得不使用反射。请注意,下面的代码中没有错误处理。您必须检查该属性是否存在以及是否具有正确的类型!

    public class Program
    {
        public static object f1() {
            return new {string1 = "a", string2 = "b"};
        }
    
        public static void Main()
        {
            var x = f1();
            var p = x.GetType().GetProperty("string1");
            string s = (string)p.GetValue(x);
            Console.WriteLine(s);
        }   
    
    }
    

    【讨论】:

      【解决方案3】:

      您可以创建一个新类来代替返回一个新对象:

      public class TestClass
      {
      public string str1{set;get;}
      public string str2{set;get;}
      }
      

      例子:

      private TestClass function1()
       {
         return new TestClass()
         {
           str1 = "a",
           str2 = "b"
         }
       }
      

      用法:

      var a = function1().str1;
      

      【讨论】:

        【解决方案4】:

        正如其他人所说,正确的方法是创建一个类来返回结果。

        但是,从 C# 7 开始,还有另一个选项称为 tuple deconstruction(注意:您至少需要像 Visual Studio 2017 中那样的 C# 7 编译器才能工作):

        private (string, string) Function1()
        {
          return ("a", "b");
        }
        
        // In your calling method:
        (string left, string right) = Function1();
        System.Console.WriteLine($"left = {left}, right = {right}.");
        

        【讨论】:

        • 这与返回课程有什么不同?
        • @DavidG,因为您返回的不是课程而是Tuple
        • “返回一个类”背后的情绪不是它是一个类,而是它是某种具体的对象。例如,可能是一个结构。所以不管是类、结构体还是元组,其实都是一样的。
        • 我明白了。我想要做的是提供现有答案的替代方案(“返回专门为此目的定义的类的实例”),同时避免其他选项的缺点,例如返回匿名类,使用反射和@987654323 @.
        猜你喜欢
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        • 2021-04-03
        • 2016-09-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多