简体   繁体   中英

How to access methods of subclass in object array C#?

How can I set/get the value of an object in an object array?

Currently I get: "object does not contain a definition for 'value' and no extension method"

Example C#;

    public class myObjClass
    {
        public int value = 5;
    }

    public class myObjClass2
    {
        public float[] pos = new float[2];
    }

    public void test()
    {
        myObjClass myObj = new myObjClass();
        myObjClass2 myObj2 = new myObjClass2();

        object[] objArr = new object[2];
        objArr[0] = myObj;
        objArr[1] = myObj2;
        Debug.Print(myObj.value.ToString());
        Debug.Print(objArr[0].value.ToString()); // how?

    }

Its because a generic object does not have the property value your class myObjClass has. To fix this you could cast the item to your class like so:

((myObjClass)objArr[0]).value.ToString()

Only do this ^ if you are sure of the type


Instead you could also check it first:

With as :

var item = objArr[0] as myObjClass;
if( item != null ) // Item will be null if its not a 'myObjClass'
{
    //Do stuff with item
}

Or with is :

if( objArr[0] is myObjClass )
{
    var item = (myObjClass)objArr[0];
    //Do stuff with item
}

When using an object array you have to cast to the real type (here: myObjClass) before accessing the fields:

You can access the object like this

((myObjClass)objArr[0]).value

but I would not recommend. Can´t you have your array to be the concrete type

var array = new myObjClass[42]

A compact safe alternative to retrieve the value is

(objArr[0] as myObjClass)?.value

You need to cast object to known type which is myObjClass , like:

((myObjClass)objArr[0]).value.ToString();

Or you can use reflection

var valueString = objArr[0].GetType().GetProperty("value").GetValue(objArr[0]);
Debug.Print(valueString.ToString()); 

Hope helps,

Technically you can put it as

  Debug.Print((objArr[0] as myObjClass)?.value.ToString()); 

We try casting objArr[0] as myObjClass and if succeed get value and turn it to string . If objArr[0] is not myObjClass we return null as a string

However, a much better way is to implement ToString() in both classes of interest:

public class myObjClass
{
    public int value = 5;

    public override string ToString() {
      // When debugging we want to know "value"
      return value.ToString();
    }
}

public class myObjClass2
{
    public float[] pos = new float[2];

    public override string ToString() {
      // When debugging we want to know "pos[0]" and "pos[1]" values
      return $"{pos[0]} : {pos[1]}";
    }
}

And then put an easy

// Just print out debug info (we don't want to know the actual objArr[0] class)
Debug.Print(objArr[0].ToString());

You have a single object, that indeed is an instance of myObjClass , and has a value field, but you have two references to it.

One ( myObj ) is known to the compiler to be of type myObjClass , and it can guarantee that it has a value field.

The other ( objArr[0] ) is only known to the compiler to be of type object , and it cannot guarantee that it has a value field.

For example, you could do:

 objArr[0] = (random.Next() > 0.5) : myObj ? myObj2

where we're gonna decide at runtime, based on the value of a random number, which will be the type of the actual object at objArr[0] .

So, if this was allowed, half of the time objArr[0].value would be correct, and half of the time it will be an error.

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