简体   繁体   中英

Assigning an object to a Property of type object

After lots of looking around (including SIMILAR but not same questions), I hope my question will make sense and someone could help me resolve this.

I have many classes, say ClassA, ClassB, ClassC etc and they all exist for specific reasons. I have another Class which is being used for testing purposes and this includes two properties, set as follows:

  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()
    {
    }

   }

My problem is this: I instantiate the class, ie Test myTest = new Test(); etc and I need to assign a class, say myResult (containing dozens of properties with values).

I need to do (something like) this:

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

It is safe to assume that later, if for example there's a myResult.SomeProperty with value 18, I would like to see it from myTest.testDataResult.SomeProperty Ie

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

Is this possible? Being looking all around Binaryformatters and Reflection, one example seemed also good ( https://www.codeproject.com/Articles/1111658/Fast-Deep-Copy-by-Expression-Trees-C-Sharp ) mentioned as link here in SO ( Faster deep cloning ) but I couldn't make it, is above my experience level.

Could someone help me please with a working example?

If I understood correctly, it seems to me you are mixing up things.

When you assign something to object, you are saying that you are putting your instance in a box which has no outstanding type. This means that when you want to read that instance, you first have to cast it to the correct type in order to access the properties.

You have to do something like this:

(SomeClss() myTest.testDataResult).Property1

For this reason, you should try to introduce a type, which could be an interface, to describe the minimum set of methods and properties that you require. If you can't, no problem, you just have to cast. Keep in mind that the latter approach may crash at runtime if you choose the incorrect type, while the former one allows you to spot mistakes at compile time.

I'd assume the simplest way of doing this is making your Test class generic:

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

That will allow you to access all the properties of your test data result instances without any black magic.

object is a class, like most other. You can inherit from it, instantiate objects of it (but you only do that rarely), declare a variable of it's type. There are however 2 special rules owing to it's singular historic/design position:

  1. Every single class implicitly or explicitly inherits from object. If you define no baseclass, object is appplied implicitly. If you define a baseclass, you just have to go back far enough it's inheritance chain and you will find object. The type object is the root of every class heirarchy.

  2. While Numeric Types, structs and co do not inherit from Object, they can be boxed into object. It looks very similar, but there are differences in details.

As a result every single imaginable type in .NET can be assigned to a variable of type object. It either is a object anyway so inheritance takes over, or it can be boxed into one. Now we do not use object as a type a lot anymore. While you can assign anything to object, you loose the compile time type checks while doing so. And that is a very important thing to loose. I would never sacrifice it, if I can help it.

Generics vs object

Using object as type has fallen out of favor with generics. The lock statement is one of the rare cases where you still create a variable of type object and explicitly create a isntance of object. You will find the type object used for the sender in Event Handlers (this is 50% convetion, 50% usefull). Pretty much everywhere else we use generics.

Generics have been added to the Framework and language specifically to avoid having to resort to object as a variable type anymore. And I picked "resort to" very intentionally. The Generic Collections like List<T> , Queue<T> and Dictionary<TKey,TValue> replaced the pre-generic ones like Queue, HashTable and wichever one we used instead of list.

We can not really figure out what your goal is. However it does sound a lot like a XY Problem, simply because using object as a variable type is part of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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