1

以下示例来自《Programming in the Key of C# 》一书。

程序的第一次迭代是典型的 C 方式来做,下一次轮回更加面向对象。该程序是一个简单的示例,用于计算特定事件发生在一年中的哪一天(如果是闰年,12 月 31 日是 365 或 366)。

using System;

class StructureAndMethodsTwo
{
    static void Main()
    {
        Date dateMoonWalk = new Date();

        dateMoonWalk.iYear = 1969;
        dateMoonWalk.iMonth = 7;
        dateMoonWalk.iDay = 20;

        Console.WriteLine("Moon walk: {0}/{1}/{2} Day of Year: {3}", 
            dateMoonWalk.iMonth, dateMoonWalk.iDay, dateMoonWalk.iYear,
            Date.DayOfYear(dateMoonWalk));
    }
}

struct Date
{
    public int iYear;
    public int iMonth;
    public int iDay;

    public static bool IsLeapYear(int iYear)
    {
        return iYear % 4 == 0 && (iYear % 100 != 0 || iYear % 400 == 0);
    }

    static int[] aiCumulativeDays = { 0, 31, 59, 90, 120, 151,
                                        181, 212, 243, 273, 304, 334 };

    public static int DayOfYear(Date dateParam)
    {
        return aiCumulativeDays[dateParam.iMonth - 1] + dateParam.iDay +
            (dateParam.iMonth > 2 && IsLeapYear(dateParam.iYear) ? 1 : 0);
    }
}

程序的下一个版本是相同的,除了DayOfYear变成的方法

public int DayOfYear()
{
return aiCumulativeDays[iMonth -1] + iDay+ (iMonth > 2 && IsLeapYear(iYear) ? 1:0);
}

在第二个版本中究竟发生了什么使它比第一个更适合 OOP?该方法是否在第一次迭代Date中创建了一个类型的对象?DayOfYear我知道该方法的实例版本可以直接访问结构的字段,但我不知道它的明显优势。

4

3 回答 3

1

在第二个版本中,对象本身提供了所有信息,而不是静态上下文中的日期参数。如果该方法使用对象自己的数据,而不是通过参数“告知”它是什么,那么它就更加面向对象。

于 2012-09-21T14:59:21.470 回答
1

在第一个版本中,一年中的某一天没有创建日期。它只是评估参数。第二个版本更加面向对象,因为它对类的实例而不是静态方法调用进行操作。这通常会使事情更有条理,并且更加面向对象。

于 2012-09-21T15:00:41.327 回答
1

在示例二中,您使用的iYear, iMonth and iDay是 Date 结构的内部变量。第一个示例使用您传递给不需要的 DayOfYearFunction 的 Date 对象的另一个副本。

编辑:

在第一个示例中,您使用 Date 结构的实例并将其作为参数传递给 DayOfYear 函数,Date (dateParam) 的实例在堆栈上分配,这将使用更多内存并需要来自 CLR 的额外垃圾回收调用需要清理的时候。

性能问题: IMO,虽然使用了更多的内存,但由于程序的性质,几乎不会出现任何性能问题。它只是一个冗余参数。

于 2012-09-21T15:01:01.000 回答