【问题标题】:Assigning an object to a Property of type object将对象分配给对象类型的属性
【发布时间】:2020-05-22 22:44:49
【问题描述】:

经过大量环顾(包括类似但不相同的问题),我希望我的问题是有意义的,有人可以帮助我解决这个问题。

我有很多类,比如 ClassA、ClassB、ClassC 等,它们都出于特定原因而存在。 我有另一个用于测试目的的类,它包括两个属性,设置如下:

  public class Test : Countable<TestScenario>
  {


    //test completed
    public bool completed { get; set; } = false;

    //break or error (stop further execution) or not
    public bool breakOnError { get; set; } = true;

    //test result
    public bool success { get; set; } = false;

    //what did we test
    public string testCase { get; set; } = string.Empty;

    //what data we got as result
    public object testDataResult { get; set; }

    public Test()
    {
    }

   }

我的问题是:我实例化了这个类,即 Test myTest = new Test();等等,我需要分配一个类,比如 myResult(包含几十个带值的属性)。

我需要这样做(类似):

    Test myTest = new Test();
     myTest.testDataResult = myResult;

可以安全地假设,例如,如果有一个值为 18 的 myResult.SomeProperty,我想从 myTest.testDataResult.SomeProperty 中查看它 即

Console.WriteLine(myTest.testDataResult.SomeProperty.ToString());
//18

这可能吗?环顾四周 Binaryformatters 和 Reflection,一个例子似乎也不错 (https://www.codeproject.com/Articles/1111658/Fast-Deep-Copy-by-Expression-Trees-C-Sharp) 在 SO (Faster deep cloning) 中作为链接提到,但我做不到,这超出了我的经验水平。

有人可以帮我举一个可行的例子吗?

【问题讨论】:

  • 超过一半的代码与您在此处尝试询问的内容无关。请更新帖子以包含复制您的问题所需的代码,以便我们为您提供帮助。 and after lots of things that got executed, a final task returns one (of hundreds..) or objects 这是什么意思,我在代码中没有看到任何这些东西......
  • @Çöđěxěŕ 抱歉,我只是举了一个例子,说明我有什么以及我需要去哪里,如果可能的话。我没有其他代码,试图弄清楚如何去做.. 感谢您查找此内容,谢谢。
  • 没有理由道歉,没关系 :) 恐怕我不明白你在这里的意图。
  • @Çöđěxěŕ 按照建议编辑了问题的描述。
  • @ Çöđěxěŕ 我有许多方法返回 obj(类),每个方法都不同,例如 myClassA、myObjectB 等,其中包含值。我正在尝试将整个类分配给一个名为 Test 的类的属性。原因是,我试图创建特定类型的属性,即public objectA myProperty1 {get; set;},然后是public objectB myProperty2 {get; set;} 等,但是不同类型的类太多(objectA、B..等)所以我想知道我是否可以声明一个通用属性,如public object myProperty {get; set;} 然后关闭(当然一次一个)我需要的任何对象...

标签: c# properties copy clone


【解决方案1】:

如果我理解正确,在我看来你是在搞混。

当你给对象赋值时,你是说你把你的实例放在一个没有突出类型的盒子里。这意味着当您想要读取该实例时,您首先必须将其转换为正确的类型才能访问属性。

你必须这样做:

(SomeClss() myTest.testDataResult).Property1

因此,您应该尝试引入一种类型(可以是接口)来描述您需要的最少方法和属性集。如果你不能,没问题,你只需要投射。请记住,如果您选择了不正确的类型,后一种方法可能会在运行时崩溃,而前一种方法可以让您在编译时发现错误。

【讨论】:

  • 谢谢大家。在这背后的动机中加点盐:我确实有很多(超过 80 个)异步任务,每个任务都返回一个对象。实际上,每个对象都可以返回多个对象之一,并且都是具有链接类和属性的类。例如,异步任务A在一个实例上返回objX12(有obj1到12),并且每个对象都有不同的属性(尽管很多都是相似的..无论如何)。因此,创建一个具有 aaaall 属性的 TestResults 类,然后根据返回的对象(当每个任务完成时......)在 TestResults 中分配来自 objX... 的结果是非常困难的
  • 因此,我有一个相当简单的 TestResults 类,我试图将一个对象放入一个属性中,当然如果可行的话(我不是专家..),因此我研究了一种方法它。只要我可以“达到”原始属性的名称和值,任何方式都足够了:例如,如果我可以在属性TestResults.myData 中以某种方式分配myObjA(假设myObjA 有一个属性Age)我希望我可以使用TestResults.myData.Age 等。希望有办法.. 谢谢!
【解决方案2】:

我认为最简单的方法是让您的 Test 类通用:

public class Test<TResult> : Countable<TestScenario>
{
  // ... the test outcome properties listed above
  public TResult testDataResult { get; set; }
  // ... constructor
}

这将允许您访问测试数据结果实例的所有属性,而无需任何黑魔法。

【讨论】:

    【解决方案3】:

    object 是一个类,就像大多数其他的一样。您可以从它继承,实例化它的对象(但您很少这样做),声明它的类型的变量。然而,由于其独特的历史/设计位置,有 2 条特殊规则:

    1. 每个类都隐式或显式地从对象继承。如果未定义基类,则隐式应用对象。如果你定义一个基类,你只需要回到足够远的继承链,你就会找到对象。类型对象是每个类层次结构的根。

    2. 虽然数值类型、结构和 co 不从 Object 继承,但它们可以装箱到对象中。它看起来非常相似,但在细节上存在差异。

    因此,.NET 中每个可以想象的类型都可以分配给对象类型的变量。它要么是一个对象,所以继承接管,或者它可以被装箱成一个。现在我们不再使用 object 作为类型了。虽然您可以将任何内容分配给对象,但这样做时您会失去编译时类型检查。这是放松的非常重要的事情。如果我能帮上忙,我绝不会牺牲它。

    泛型与对象

    使用对象作为类型已经不再受泛型的青睐。 lock statement 是您仍然创建对象类型变量并显式创建对象实例的极少数情况之一。您将在事件处理程序中找到用于sender 的类型对象(这是 50% 的对流,50% 的有用)。我们几乎在其他任何地方都使用泛型。

    已将泛型添加到框架和语言中,专门是为了避免不得不求助将对象作为变量类型。我非常有意地选择了“诉诸于”。 List&lt;T&gt;Queue&lt;T&gt;Dictionary&lt;TKey,TValue&gt; 等通用集合取代了 Queue、HashTable 等前通用集合,以及我们使用的任何一个代替列表的集合。

    我们无法真正弄清楚您的目标是什么。然而,这听起来确实很像一个 XY 问题,仅仅是因为使用对象作为变量类型是其中的一部分。

    【讨论】:

    • 我很感激!我将不得不对此进行一些思考,但我想我理解你的观点。我有太多不同的课程。因此,我希望将我需要的任何类的属性集合“分配”给“通用”排序属性。请注意,每个类都有链接的类,所以我需要几个月的时间才能通过更直接的方式。想象一下 ClassA(具有 X 属性,这些 Y 属性中的类型是 ClassB 等),并且有许多值那些属性。所以我需要一种方法将它们作为 ClassA “放入”属性中..
    • @Nick 到目前为止,这听起来像是一个无聊的普通课程。类实例通常有一堆不同类型的字段或属性。它们具有不同参数和返回值类型的功能。 |如果是 1:N 关系,通常需要ClassB[]List&lt;ClassB&gt; 或类似的集合。
    猜你喜欢
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 2010-11-15
    • 2016-01-15
    相关资源
    最近更新 更多