【问题标题】:C# store Stopwatch in array object and handle itC#将秒表存储在数组对象中并处理它
【发布时间】:2014-07-04 23:40:30
【问题描述】:

我有一个对象数组,我在其中存储不同的值类型。 其中一种类型是秒表。我该如何处理? 我应该将数组元素转换为什么才能将其作为秒表处理?

这是我的代码外观的小型复制器

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

【问题讨论】:

  • “我应该如何处理它”是什么意思?如果要从数组中取回 Stopwatch 对象,请将对象强制转换回 System.Diagnostics.Stopwatch
  • 问题是我不能把数组的元素当作秒表处理
  • 你听说过类吗? :D
  • 是的,但是当我想声明一个新的对象数组并像旧的一样更新它时,我只是这样做 newobject[] = oldobject[];我不知道使用具有类型的类是否相同。我认为我们必须一一更新它们吗?
  • 我相信你所做的只是设置newobject——如果它是一个数组,它是一个引用类型——指向oldobject。您并没有创建对象的新副本,而只是创建了一种引用它们的新方法。请参阅此问答:stackoverflow.com/questions/1533757/…

标签: c# arrays stopwatch


【解决方案1】:

也许你应该为此写一堂课?

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

然后要使用这个类,你只需要调用Stopwatch 属性:

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

现在,如果您只是想知道以毫秒为单位实例化一个数组需要多长时间,您有两种选择:

  • 使用像dotTrace这样的性能分析工具
  • 在您的数组创建代码外部实例化秒表

像这样:

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

无论哪种方式,首先找出您要完成的工作会很好。

【讨论】:

  • 如果我的数组元素类型改变了怎么办?我的意思是 object[1] 有时可以是 int,然后更改为 double,然后更改为秒表等...
  • 我想指出的是,将不同类型的数据放入数组中是非常糟糕的做法。这被称为原始痴迷,它被认为是应该避免的代码异味。 c2.com/cgi/wiki?PrimitiveObsession
【解决方案2】:

您有一个 object 数组,因此您必须强制转换每个元素才能访问其类型特定的属性和方法:

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

顺便说一句,传递object 数组通常不是一个好主意。您丢失了类型信息,因此,如果您将其中一个元素更改为不同的类型,您现在需要更新执行该元素强制转换的代码。更喜欢创建自己的类型来保存所有这些数据。

【讨论】:

  • 我的演员阵容不正确。只是在元素之前铸造秒表,我没有任何结果。谢谢。至于创建我自己的类型来保存数据,看起来有点复杂,谢谢大家
  • @user2530266 我还是不明白你为什么首先使用对象数组。
  • @user2530266:相信我;从长远来看,它远没有那么复杂,而且你需要了解它。真的不难。在提供类型安全的语言中解决类型安全问题总是一个坏主意。
  • 但在我的对象中,我的类型值并不总是相同的。所以 object[1] 有时可以是 int,有时是 double 等等......这就是我在我的案例中使用 object 的原因。
  • 有谁知道为什么我不能在函数外重新启动或重置它?
【解决方案3】:

我不完全确定我理解您遇到的问题,但假设它基于将您的 Stopwatch 元素放入 object 的数组中,此代码应该适合您:

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

此代码假定您知道元素 5 将始终是 Stopwatch:如果不是,您将收到运行时错误。

【讨论】:

    【解决方案4】:

    在转换之前检查对象的类型

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

    或检查演员表是否有效

    var sw = obj[5] as System.Diaogstics.Stopwatch;
    if (sw != null) {
        Console.WriteLine(sw.Elapsed.TotalMilliseconds);
    }
    

    【讨论】:

      【解决方案5】:

      你会cast它。

      如果强制转换无效 - 如果对象实际上不是秒表,则此强制转换将引发 InvalidCastException:

      var stopwatch = (Stopwatch)testobject[5];
      

      as operator,如果它不是秒表,它将返回 null:

      var stopwatch = testobject[5] as Stopwatch;
      

      顺便说一句,您在上面展示的数据结构带有糟糕设计的味道。真的没有必要有这么不“typesafe”的东西。您应该根据您的代码来准确地为您提供所需的内容,而不是在运行时强制转换。因为如果你做错了——如果你尝试像var x = (Stopwatch)object[4] 这样的东西——那么编译器就不会捕捉到它,你会得到一个愤怒的客户报告运行时崩溃。

      一般来说,更喜欢将对象实例存储为它们的实际类型,而不是原始的objects。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-28
        • 2020-08-24
        • 2012-10-08
        • 1970-01-01
        • 2021-02-07
        • 2021-12-21
        相关资源
        最近更新 更多