7

我正在开发一个从 Excel 文件中提取数据的应用程序(我无权访问实际数据库),并且我编写了一个方法,该方法具有从 Excel 电子表格中提取数据的唯一功能,如下所示.

private IEnumerable<SMEntity> ExtractSMData(List<MSExcel.Range> SMData)
{
    List<SMEntity> SMEntities = new List<SMEntity>();

    foreach (MSExcel.Range Row in SMData)
    {
        SMEntity entity = new SMEntity();
        entity.IncidentNumber = Row.get_Range("K1").get_Value();
        entity.SRNumber = Row.get_Range("L1").get_Value();
        entity.SRCategory = Row.get_Range("M1").get_Value();
        entity.SiebelClientCall = EntityConversions.DateTimeConversion(Row.get_Range("N1").get_Value());
        entity.SiebelOpenedDate = EntityConversions.DateTimeConversion(Row.get_Range("O1").get_Value());
        entity.IncidentOpenDate = EntityConversions.DateTimeConversion(Row.get_Range("P1").get_Value());
        entity.PickedUpBeforeClient = Row.get_Range("Q1").get_Value().ToString().ToLowerCase() == "no" ? false : true;
        entity.OutageStartTime = EntityConversions.DateTimeConversion(Row.get_Range("R1").get_Value());
        entity.DetectionPoint = EntityConversions.DateTimeConversion(Row.get_Range("S1").get_Value());
        entity.SecondsToDetection = EntityConversions.ConvertDetectionTimeToInt(Row.get_Range("T1").get_Value());
        entity.OutageEndTime = EntityConversions.DateTimeConversion(Row.get_Range("U1").get_Value());
        entity.MTTR = EntityConversions.ConvertMTTRStringToInt(Row.get_Range("V1").get_Value());
        entity.RepairedOnTime = Row.get_Range("W1").get_Value().ToString().ToLowerCase() == "no" ? false : true;
        SMEntities.Add(entity);
    }

    return SMEntities;
}

我已经运行了代码分析(我正在使用 Visual Studio 2012 并在 .NET 4.5 中开发)并且我有一个CA1502: Avoid excessive complexity(复制如下)。作为一名初级开发人员(我今年 17 岁),我尝试使用 MSDN 了解更多有关此内容的信息,但是,我对为什么我的圈复杂度为 33 感到有些困惑。

CA1502

避免过度复杂

'Extraction.ExtractSMData(List<Range>)'圈复杂度为 33。重写或重构方法以将复杂度降低到 25。

Core.Extraction.cs:104

我可以通过我的快速如果(condition ? if_true : if_false,这些叫什么?)看到它可能很糟糕,但我仍然只能将其视为 5。

更新

圈复杂度现在是 33...

如果我注释掉entity.IncidentNumber = Row.get_Range("K1").get_Value();复杂性变为 32。我认为get_Range()并且get_Value()每个人都是一个,但还好......

如果我注释掉entity.RepairedOnTime = Row.get_Range("W1").get_Value().ToString().ToLower() == "no" ? false : true;复杂度变成 28 ......

get_Range(), get_Value(), quick-if 是 3,做ToString()和数ToLower()

4

2 回答 2

1

我将方法本身、foreach和两个条件运算符的复杂度计算为总共 4 个。如果 13 次调用中的每一个get_Range都值得 +1 复杂度,并且 13 次调用中的每一个get_Value都值得 +1 复杂度,那么总复杂度将加起来为 30(仍然是 1 短,但接近)。我不确定为什么这两个函数会增加复杂性,但这似乎是合理的。

尝试删除其中一条调用get_Rangeget_Value查看圈复杂度是否下降到 29。

于 2012-12-06T13:28:00.593 回答
-1

您的返回类型是 IEnumerable,所以不要使用列表。这使得 IENumerable 毫无用处。否则你不使用 Lazy-Evaluation 请参阅:http: //blogs.msdn.com/b/pedram/archive/2007/06/02/lazy-evaluation-in-c.aspx

最好使用 yield return :

private IEnumerable<SMEntity> ExtractSMData(List<MSExcel.Range> SMData)
{
    foreach (MSExcel.Range Row in SMData)
    {
        SMEntity entity = new SMEntity();

        entity.IncidentNumber = Row.get_Range("K1").get_Value();
        entity.SRNumber = Row.get_Range("L1").get_Value();
        entity.SRCategory = Row.get_Range("M1").get_Value();
        entity.PickedUpBeforeClient = !Row.get_Range("Q1").get_Value().ToString().ToLowerCase() == "no"
        entity.RepairedOnTime = !Row.get_Range("W1").get_Value().ToString().ToLowerCase() == "no"

        entity.SiebelClientCall = EntityConversions.DateTimeConversion(Row.get_Range("N1").get_Value());
        entity.SiebelOpenedDate = EntityConversions.DateTimeConversion(Row.get_Range("O1").get_Value());
        entity.IncidentOpenDate = EntityConversions.DateTimeConversion(Row.get_Range("P1").get_Value());
        entity.OutageStartTime = EntityConversions.DateTimeConversion(Row.get_Range("R1").get_Value());
        entity.DetectionPoint = EntityConversions.DateTimeConversion(Row.get_Range("S1").get_Value());
        entity.OutageEndTime = EntityConversions.DateTimeConversion(Row.get_Range("U1").get_Value());


        entity.MTTR = EntityConversions.ConvertMTTRStringToInt(Row.get_Range("V1").get_Value());
        entity.SecondsToDetection = EntityConversions.ConvertDetectionTimeToInt(Row.get_Range("T1").get_Value());


        yield return entity;
    }

}

你也可以这样写:

private IEnumerable<SMEntity> ExtractSMData(List<MSExcel.Range> SMData)
{
    foreach (MSExcel.Range Row in SMData)
    {
        yield return new SMEntity 
        {

            IncidentNumber = Row.get_Range("K1").get_Value(),
            SRNumber = Row.get_Range("L1").get_Value(),
            SRCategory = Row.get_Range("M1").get_Value(),
            PickedUpBeforeClient = !Row.get_Range("Q1").get_Value().ToString().ToLowerCase() == "no"
            RepairedOnTime = !Row.get_Range("W1").get_Value().ToString().ToLowerCase() == "no"

            SiebelClientCall = EntityConversions.DateTimeConversion(Row.get_Range("N1").get_Value()),
            SiebelOpenedDate = EntityConversions.DateTimeConversion(Row.get_Range("O1").get_Value()),
            IncidentOpenDate = EntityConversions.DateTimeConversion(Row.get_Range("P1").get_Value()),
            OutageStartTime = EntityConversions.DateTimeConversion(Row.get_Range("R1").get_Value()),
            DetectionPoint = EntityConversions.DateTimeConversion(Row.get_Range("S1").get_Value()),
            OutageEndTime = EntityConversions.DateTimeConversion(Row.get_Range("U1").get_Value()),


            MTTR = EntityConversions.ConvertMTTRStringToInt(Row.get_Range("V1").get_Value()),
            SecondsToDetection = EntityConversions.ConvertDetectionTimeToInt(Row.get_Range("T1").get_Value())
        };
    }
}
于 2012-12-06T13:42:09.397 回答