0

I have an array of objects where i store different value types inside. One of those types is a stopwatch. How can i handle it? To what should i convert the array ellement to be able to handle it as a stopwatch?

Here is a small reproducer of how my code looks like

public static object[] test()
    {
        object[] obj = new object[6];

        obj[0] = bool;
        obj[1] = string;
        obj[2] = double;
        obj[3] = float;
        obj[4] = int;
        obj[5] = System.Diagnostics.Stopwatch.StartNew();

        return obj;
    }

    object[] testobject = new object[6];
    testobject = test();
    Console.WriteLine(testobject[5].Elapsed.TotalMilliseconds);   //handle stopwatch
user2530266
  • 287
  • 3
  • 18
  • What do you mean by "How should I handle it?" If you want to get a `Stopwatch` object back out of your array, cast the object back to `System.Diagnostics.Stopwatch`. – Ann L. Jul 04 '14 at 23:42
  • The problem is that i can not handle the array's element as a stopwatch – user2530266 Jul 04 '14 at 23:43
  • Have you heard of Classes? :D – Jon Limjap Jul 04 '14 at 23:56
  • Yes but when i want to declare a new array of objects and update it same as the old one i just do it like this newobject[] = oldobject[]; I dont know if it is the same using classes with types. I think we have to update them all one by one do we? – user2530266 Jul 05 '14 at 00:12
  • I believe that all you're doing there is setting `newobject` - which, if it's an array, is a reference type - to point to `oldobject`. You aren't creating new copies of your objects, you're just creating a new way to refer to them. See this Q+A: http://stackoverflow.com/questions/1533757/is-int-a-reference-type-or-a-value-type. – Ann L. Jul 06 '14 at 14:07

5 Answers5

4

Maybe you should write down a class for this?

public class MyObject
{
    public bool SomeBool {get; set;}
    public string SomeString {get; set;}
    public double SomeDouble {get; set;}
    public float SomeFloat {get; set;}
    public int SomeInt {get; set;}
    public System.Diagnostics.Stopwatch Stopwatch {get; set;}

    public MyObject()
    {
        this.Stopwatch = System.Diagnostics.Stopwatch.StartNew();
    }
}

Then to use this class you just need to call on the Stopwatch property:

var myObject = new MyObject();
Console.WriteLine(myObject.Stopwatch.Elapsed.TotalMilliseconds);

Now, if you're seriously just wanting to find out how long it takes to instantiate an array in milliseconds, you have two options:

  • Use a performance profiling tool like dotTrace
  • Instantiate a stopwatch outside your array creation code

Like this:

var stopWatch = System.Diagnostics.Stopwatch.StartNew();
//create your array here
Console.WriteLine(stopWatch.Elapsed.TotalMilliseconds);

Either way it would be nice to find out what you're trying to accomplish in the first place.

Jon Limjap
  • 94,284
  • 15
  • 101
  • 152
  • What if my arrays elements type change? I mean object[1] can sometimes be int, then change to double, then to stopwatch etc... – user2530266 Jul 05 '14 at 11:29
  • 1
    What I'm trying to point out is that it's pretty much bad practice to put in data of different types into an array. This is called primitive obsession and it is considered as a code smell that should be avoided. http://c2.com/cgi/wiki?PrimitiveObsession – Jon Limjap Jul 05 '14 at 13:31
1

You would cast it.

This cast will throw an InvalidCastException if the cast is invalid - if the object isn't actually a Stopwatch:

var stopwatch = (Stopwatch)testobject[5];

This, the as operator, will give you back a null instead if it's not a Stopwatch:

var stopwatch = testobject[5] as Stopwatch;

As an aside, the data structure you've shown above smells of bad design. It really shouldn't be necessary to have something so un-"typesafe". You should be depending on your code to give you exactly what you need, rather than forcing a conversion at runtime. Because if you do it wrong - if you try something like var x = (Stopwatch)object[4] - then the compiler won't catch it, and you'll get an angry customer reporting a runtime crash.

In general, prefer to store object instances as their actual types, rather than as raw objects.

Community
  • 1
  • 1
Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
1

You have an array of object, so you have to cast each element to get access to its type specific properties and methods:

Console.WriteLine(((Stopwatch)testobject[5]).Elapsed.TotalMilliseconds);

On a side note, passing around object arrays is not typically a great idea. You lose your type information, so if, say, you change one of those elements to a different type, you now need to update code which performs a cast of that element. Prefer creating your own type to hold all of that data.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • I was not doing the cast correctly. Was just casting stopwatch before the element and i wasn't having any results. Thanks. As for creating my own type to hold the data, it is a little more complicated as it looks like Thank you everyone – user2530266 Jul 04 '14 at 23:51
  • @user2530266 I still don't understand why you're using object arrays in the first place. – Jon Limjap Jul 05 '14 at 00:11
  • 1
    @user2530266: Trust me; it's far less complicated in the long run, and it's something you're going to need to understand. It really isn't difficult. Working around type safety in a language which provides it is always a bad idea. – Ed S. Jul 05 '14 at 01:36
  • But in my objects my types values aren't always the same. So object[1] can sometimes be int, sometimes be double etc... That is why i use object in my case. – user2530266 Jul 05 '14 at 11:28
  • And does anyone knows why i can not restart it or reset it outside the function? – user2530266 Jul 05 '14 at 11:32
  • To continue what @JonLimjap said: if sometimes you need a double, sometimes an int, sometimes something else, it seems likely that you have several different conceptual entities that sometimes need the same treatment. – Ann L. Jul 06 '14 at 14:02
1

I'm not completely sure I understand what problem you're having, but on the assumption that it's based on having put your Stopwatch element into an array of object, this code should work for you:

object[] testobject = test();  
System.Diagnostics.Stopwatch stopwatch = (System.Diagnostics.Stopwatch) testobject[5];
Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds);  

This code assumes that you know element 5 will always be a Stopwatch: if it isn't, you'll get a run-time error.

Ann L.
  • 13,760
  • 5
  • 35
  • 66
1

checking the type of the object before casting

if (obj[5] is System.Diagnostics.Stopwatch) {
    Console.WriteLine(((System.Diagnostics.StopWatch)obj[5]).Elapsed.TotalMilliseconds);
}

or checking if cast is working

var sw = obj[5] as System.Diaogstics.Stopwatch;
if (sw != null) {
    Console.WriteLine(sw.Elapsed.TotalMilliseconds);
}
Icepickle
  • 12,689
  • 3
  • 34
  • 48