当前位置:坤哥网-kwan-sonar 扫出的 c# 问题解决记录

sonar 扫出的 c# 问题解决记录

2021/6/28 10:08:32 IT综合阅读(130) 评论(0)

实际发布时间 2019年12月30日

    一、bug

    Handle the exception or explain in a comment why it can be ignored

    如 CommonTool.cs :

    catch (Exception){}

    修改 cath 部分:

    catch (Exception ex){
        _logger.Error($"异常[{ex.Message}][{ex}]");}

    Use a StringBuilder instead

    如 CommonTool:

    string filePath = string.Empty;foreach (var son in arr){
        filePath += "/" + son;}

    用StringBuilder,修改如下:

    StringBuilder filePath = new StringBuilder;foreach (var son in arr){
        filePath.Append( "/" + son);}

    Remove this useless assignment to local variable "fileByte"

    CommonTool.cs :

    byte[] fileByte = new byte[length];fileByte = Convert.FromBase64String(base64String);

    修改如下:

    var fileByte = Convert.FromBase64String(base64String);

    Define the locale to be used in this string operation

    规则:

    string.ToLower(), ToUpper, IndexOf, LastIndexOf, and Compare are all culture-dependent, as are some (floating point number and DateTime-related) calls to ToString. Fortunately, all have variants which accept an argument specifying the culture or formatter to use. Leave that argument off and the call will use the system default culture, possibly creating problems with international characters.string.CompareTo() is also culture specific, but has no overload that takes a culture information, so instead it's better to use CompareOrdinal, or Compare with culture.Calls without a culture may work fine in the system's "home" environment, but break in ways that are extremely difficult to diagnose for customers who use different encodings. Such bugs can be nearly, if not completely, impossible to reproduce when it's time to fix them.Noncompliant Code Examplevar lowered = someString.ToLower(); //NoncompliantCompliant Solutionvar lowered = someString.ToLower(CultureInfo.InvariantCulture);orvar lowered = someString.ToLowerInvariant();

    CommonTool.cs :

    string localFilePath = CommonTool.GenerateLocalFilePath(filePath.Substring(filePath.LastIndexOf(".")));

    改成:

     string localFilePath = CommonTool.GenerateLocalFilePath(filePath.Substring(filePath.LastIndexOf(".", StringComparison.InvariantCulture)));

    Handle the exception or explain in a comment why it can be ignored.

    规则:

    When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.
    
    This rule only reports on empty catch clauses that catch generic Exceptions.

    如:

    catch (Exception) { }

    改成:

    catch (Exception ex) { _logger.Info($"[{ex.Message}][{ex}]"); }

    Change this condition so that it does not always evaluate to "true".

    规则:

    Conditional statements using a condition which cannot be anything but false have the effect of making blocks of code non-functional. If the condition cannot evaluate to anything but true, the conditional statement is completely redundant, and makes the code less readable.
    
    It is quite likely that the code does not match the programmer's intent.
    
    Either the condition should be removed or it should be updated so that it does not always evaluate to true or false.
    
    Noncompliant Code Example
    var foo = true;
    // ...
    if (foo) // Noncompliant, always true
    {
    }

    Consider using "throw;" to preserve the stack trace

    规则:

    When rethrowing an exception, you should do it by simply calling throw; and not throw exc;, because the stack trace is reset with the second syntax, making debugging a lot harder.Noncompliant Code Exampletry{}catch(ExceptionType1 exc){
      Console.WriteLine(exc);
      throw exc; // Noncompliant; stacktrace is reset}catch (ExceptionType2 exc){
      throw new Exception("My custom message", exc);  // Compliant; stack trace preserved}Compliant Solutiontry{}catch(ExceptionType1 exc){
      Console.WriteLine(exc);
      throw;}catch (ExceptionType2 exc){
      throw new Exception("My custom message", exc);}

    如:

    catch (Exception ex){
        logger.Error("read ftpconfig err2", ex);
        throw (ex);}

    改成:

    catch (Exception ex){
        logger.Error("read ftpconfig err2", ex);
        throw;}

    Correct this "&" to "&&"

    代码范例:

    if (ResponseByte != null & ResponseByte.Length > 0){
        ...}

    修改后:

    if (ResponseByte != null && ResponseByte.Length > 0){
        ...}

    二、坏味道

    Optional parameters should not be used

    如:

    /// <summary>/// 获取配置的值/// </summary>/// <param name="key"></param>/// <param name="defaultVal"></param>/// <returns></returns>public string GetCfgVal(string key,string defaultVal=""){
        return config.GetProperty(key, defaultVal);}

    应改成:

    /// <summary>/// 获取配置的值/// </summary>/// <param name="key"></param>/// <param name="defaultVal"></param>/// <returns></returns>public string GetCfgVal(string key){
        return config.GetProperty(key, "");}/// <summary>/// 获取配置的值/// </summary>/// <param name="key"></param>/// <param name="defaultVal"></param>/// <returns></returns>public string GetCfgVal(string key, string defaultVal){
        return config.GetProperty(key, defaultVal);}

    Sections of code should not be "commented out"

    规则描述:

    Programmers should not comment out code as it bloats programs
    and reduces readability.
    Unused code should be deleted and can be retrieved from source
    control history if required.
    See
    MISRA C:2004, 2.4 - Sections of code should not be
    "commented out".
    MISRA C++:2008, 2-7-2 - Sections of code shall not be
    "commented out" using C-style comments.
    MISRA C++:2008, 2-7-3 - Sections of code should not be
    "commented out" using C++ comments.
    MISRA C:2012, Dir. 4.4 - Sections of code should not be
    "commented out"

    范例1:

    /// <summary>/// 头路径/// </summary>//public readonly string HeadPath = ConfigurationManager.AppSettings["FileUploadDir"].ToString();/// <summary>/// UserFile类/// </summary>public UserFile UserFile{
        get;
        set;}

    修改:不用的代码删除掉。

    Methods and properties should be named in camel case

    规则描述:

    Shared naming conventions allow teams to collaborate efficiently.
    This rule checks whether or not method and property names are
    camel cased. To
    reduce noise, two consecutive upper case characters are allowed
    unless they form the whole name. So, MyXMethod is compliant,
    but
    XM on its own is not.
    Noncompliant Code Example
    public int doSomething(){...}
    Compliant Solution
    public int DoSomething(){...}
    Exceptions
    The rule ignores members in types that are marked with
    ComImportAttribute or InterfaceTypeAttribute . extern
    methods are also excluded from the check. Furthermore, when '_'
    character is found in a name, the camel casing is not enforced.
    void My_method(){...} // valid
    void My_method

    如:

    /// <summary>///抄送人地址 /// </summary>public static List<string> EmailCCAddress{
        get
        {
            var temp = GetConfig("EmailCCAddress");
            return temp.Split(new[] { ",", ",", " " }, StringSplitOptions.RemoveEmptyEntries).OfType<string>().ToList();
        }}

    将【EmailCCAddress】修改为【EmailChaoSongAddress】。

    Control flow statements "if", "switch", "for", "foreach", "while", "do" and "try" should not be nested too deeply

    意思就是层级目录太深了。

    如:

    /// <summary>/// Stamp/// </summary>/// <param name="stampFilesModel"></param>/// <returns></returns>public virtual void Stamp(StampFilesModel stampFilesModel){
        foreach (var configItem in stampFilesModel.ConfigItems)
        {
            try
            {
                if (configItem.StampConfigItems == null || configItem.StampConfigItems.Count == 0)
                {
                    stampFilesModel.IsStampSuccess = true;
                    continue;
                }
    
                var compoundSealRequestModel = CreateCompoundSealRequestModel(configItem.PDFPath, configItem.FileName, configItem.LoanKind, configItem.StampConfigItems);
    
                string respStr = HttpRequestTool.HttpJsonRequset(AppConfig.CompoundSealRequestUrl, JsonConvert.SerializeObject(compoundSealRequestModel));
                var respModel = JsonConvert.DeserializeObject<CompoundSealResponseModel>(respStr);
    
                if (respModel.IsSeccess)
                {
                    var bytes = Convert.FromBase64String(respModel.FileBufferString);
                    File.WriteAllBytes(configItem.PDFPath, bytes);
                    configItem.IsStampSuccess = true;
                    stampFilesModel.IsStampSuccess = true;
    
                    //有补传文件
                    if (!string.IsNullOrEmpty(configItem.PDFPath_Assist))
                    {
                        compoundSealRequestModel = CreateCompoundSealRequestModel(configItem.PDFPath_Assist, configItem.FileName, configItem.LoanKind, configItem.StampConfigItems);
                        respStr = HttpRequestTool.HttpJsonRequset(AppConfig.CompoundSealRequestUrl, JsonConvert.SerializeObject(compoundSealRequestModel));
                        respModel = JsonConvert.DeserializeObject<CompoundSealResponseModel>(respStr);
                        if (respModel.IsSeccess)
                        {
                            bytes = Convert.FromBase64String(respModel.FileBufferString);
                            File.WriteAllBytes(configItem.PDFPath_Assist, bytes);
                        }
                    }
                }
                else
                {
                    _logger.Info($"文件【{configItem.FileName}】Stamp失败【{respModel.Message}】");
    
                    stampFilesModel.IsStampSuccess = stampFilesModel.IsStampSuccess || false;
                }
            }
            catch (Exception ex)
            {
                _logger.Error($"文件【{configItem.FileName}】Stamp异常【{ex.Message}】【{ex.StackTrace}】");
                continue;
            }
        }}

    改成:

    /// <summary>/// Stamp/// </summary>/// <param name="stampFilesModel"></param>/// <returns></returns>public virtual void Stamp(StampFilesModel stampFilesModel){
        foreach (var configItem in stampFilesModel.ConfigItems)
        {
            try
            {
                if (configItem.StampConfigItems == null || configItem.StampConfigItems.Count == 0)
                {
                    stampFilesModel.IsStampSuccess = true;
                    continue;
                }
    
                var compoundSealRequestModel = CreateCompoundSealRequestModel(configItem.PDFPath, configItem.FileName, configItem.LoanKind, configItem.StampConfigItems);
    
                string respStr = HttpRequestTool.HttpJsonRequset(AppConfig.CompoundSealRequestUrl, JsonConvert.SerializeObject(compoundSealRequestModel));
                var respModel = JsonConvert.DeserializeObject<CompoundSealResponseModel>(respStr);
    
                if (!respModel.IsSeccess)
                {
                    _logger.Info($"文件【{configItem.FileName}】Stamp失败【{respModel.Message}】");
                    stampFilesModel.IsStampSuccess = false;
                    continue;
                }
    
                var bytes = Convert.FromBase64String(respModel.FileBufferString);
                File.WriteAllBytes(configItem.PDFPath, bytes);
                configItem.IsStampSuccess = true;
                stampFilesModel.IsStampSuccess = true;
    
                //有补传文件
                if (!string.IsNullOrEmpty(configItem.PDFPath_Assist))
                {
                    compoundSealRequestModel = CreateCompoundSealRequestModel(configItem.PDFPath_Assist, configItem.FileName, configItem.LoanKind, configItem.StampConfigItems);
                    respStr = HttpRequestTool.HttpJsonRequset(AppConfig.CompoundSealRequestUrl, JsonConvert.SerializeObject(compoundSealRequestModel));
                    respModel = JsonConvert.DeserializeObject<CompoundSealResponseModel>(respStr);                   
                }
    
                if (respModel.IsSeccess)
                {
                    bytes = Convert.FromBase64String(respModel.FileBufferString);
                    File.WriteAllBytes(configItem.PDFPath_Assist, bytes);
                }
            }
            catch (Exception ex)
            {
                _logger.Error($"文件【{configItem.FileName}】Stamp异常【{ex.Message}】【{ex.StackTrace}】");
                continue;
            }
        }}

    Remove this useless assignment to local variable 'XX'

    代码范例:

     protected virtual Tuple<bool, Dictionary<string, string>> CreateFileVariables(int bid, out string error){
        error = "";
        Dictionary<string, string> variables = new Dictionary<string, string>();
    
        try
        {
            ...
            variables = CommonTool.ConvertJson2Dic(lendingDetailJson, convertEntityConfigList);
            variables.Add("encashAmtUp", CommonTool.CmycurD(Convert.ToDecimal(variables["encashAmt"])));
            ...
        }
        catch (Exception e)
        {
            ...
            return new Tuple<bool, Dictionary<string, string>>(false, null);
        }
    
        return new Tuple<bool, Dictionary<string, string>>(true, variables);}

    改成:

     protected virtual Tuple<bool, Dictionary<string, string>> CreateFileVariables(int bid, out string error){
        error = "";
    
        try
        {
            ...
            var variables = CommonTool.ConvertJson2Dic(lendingDetailJson, convertEntityConfigList);
            variables.Add("encashAmtUp", CommonTool.CmycurD(Convert.ToDecimal(variables["encashAmt"])));
            ...
        }
        catch (Exception e)
        {
            ...
            return new Tuple<bool, Dictionary<string, string>>(false, null);
        }
    
        return new Tuple<bool, Dictionary<string, string>>(true, new Dictionary<string, string>());}

    Enumeration type names should not have "Flags" or "Enum" suffixes

    这种提示非常正确。

    微软针对Enumeration类型的命名规范:

    The enumeration (Enum) value type inherits from the Enum Class. The following rules outline the naming guidelines for enumerations:
    
    Use Pascal case for Enum types and value names.
    Use abbreviations sparingly.
    Do not use an Enum suffix on Enum type names.
    Use a singular name for most Enum types, but use a plural name for Enum types that are bit fields.
    Always add the FlagsAttribute to a bit field Enum type.

    参考地址:https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/4x252001(v=vs.71)?redirectedfrom=MSDN

    Methods and properties should be named in camel case

    规则:

    Shared naming conventions allow teams to collaborate efficiently.
    This rule checks whether or not method and property names are
    camel cased. To
    reduce noise, two consecutive upper case characters are allowed
    unless they form the whole name. So, MyXMethod is compliant,
    but
    XM on its own is not.
    Noncompliant Code Example
    public int doSomething(){...}
    Compliant Solution
    public int DoSomething(){...}
    Exceptions
    The rule ignores members in types that are marked with
    ComImportAttribute or InterfaceTypeAttribute . extern
    methods are also excluded from the check. Furthermore, when '_'
    character is found in a name, the camel casing is not enforced.
    void My_method(){...} // valid
    void My_method_(){...} // invalid, leading and trailing underscores
    are reported

    代码范例:

    public class VFPSvc

    改成:

    public class VfpSvc

    Trivial properties should be auto-implemented

    代码范例:

    private string _root;public string Root{
        get
        {
            return _root;
        }
        set
        {
            _root = value;
        }}

    改成:

    public string Root { get; set; }

    Fields that are only assigned in the constructor should be "readonly"

    意思仅在构造函数中分配的字段应为“只读”。

    代码范例:

     public sealed class ApolloConfigUtility
     {
        private Config config;
        private ApolloConfigUtility(string namespaceName)
        {
            config = ConfigService.GetConfig(namespaceName);
        }
     }

    改成:

     public sealed class ApolloConfigUtility
     {
        private readonly Config config;
        private ApolloConfigUtility(string namespaceName)
        {
            config = ConfigService.GetConfig(namespaceName);
        }
     }

    Utility classes should not have public constructors

    规则描述:

    Utility classes, which are collections of static members, are notmeant to be instantiated. Even abstract utilityclasses, which can be extended, should not have publicconstructors.C# adds an implicit public constructor to every class which doesnot explicitly define at least one constructor. Hence, at least oneprotected constructor should be defined if you wish to subclassthis utility class. Or the static keyword should be added to
    the class declaration to prevent subclassing.Noncompliant Code Examplepublic class StringUtils // Noncompliant{public static string Concatenate(string s1, string s2){return s1 + s2;}}Compliant Solutionpublic static class StringUtils{public static string Concatenate(string s1, string s2){return s1 + s2;}}orpublic class StringUtils{protected StringUtils(){}public static string Concatenate(string s1, string s2){return s1 + s2;}}

    Dead stores should be removed

    规则:

    A dead store happens when a local variable is assigned a valuethat is not read by any subsequent instruction. Calculating orretrieving a valueonly to then overwrite it or throw it away, could indicate a seriouserror in the code. Even if it's not an error, it is at best a waste of
    resources.Therefore all calculated values should be used.Noncompliant Code Examplevoid CalculateRate(int a, int b){int i;i = a + b; // Noncompliant; calculation result not used beforevalue is overwritteni = DoSomething(); // Noncompliant; retrieved value not usedfor (i = 0; i < 10; i++){// ...}// ...}Compliant Solutionvoid CalculateRate(int a, int b){int i;i = DoSomething();i += a + b;StoreI(i);for (i = 0; i < 10; i++){// ...}}Exceptions
    No issue is reported whenthe analyzed method body contains try blocks,a lambda expression captures the local variables, orthe variable is unused (case covered by Rule S1481).SeeMITRE, CWE-563 - Assignment to Variable without Use('Unused Variable')CERT, MSC13-C. - Detect and remove unused valuesCERT, MSC13-CPP. - Detect and remove unused valuesCERT, MSC56-J. - Detect and remove superfluous code andvaluesCERT, MSC12-CPP. - Detect and remove code that has no
    effect

    Collapsible "if" statements should be merged

    代码:

    //目录是否存在if (!sftp.DirectoryOrFileExist(routing, out error)){
        //创建目录
        if (!sftp.CreateDirectorys(routing, out error))
        {
            sftp.Disconnect();
            return flag;
        }}
    //目录是否存在if (!sftp.DirectoryOrFileExist(routing, out error) && !sftp.CreateDirectorys(routing, out error)){
        sftp.Disconnect();
        return flag;}

    Non-constant static fields should not be visible

    规则:

    A static field that is neither constant nor read-only is not threadsafe.Correctly accessing these fields from different threads
    needs synchronization with lock s. Improper synchronization may
    lead to unexpected results, thus publicly visible static fields are
    best
    suited for storing non-changing data shared by many consumers.To enforce this intent, these fields should be marked readonly orconverted to constants.Noncompliant Code Examplepublic class Math{public static double Pi = 3.14; // Noncompliant}orpublic class Shape{public static Shape Empty = new EmptyShape(); // Noncompliantprivate class EmptyShape : Shape{}}Compliant Solutionpublic class Math{public const double Pi = 3.14;}orpublic class Shape{public static readonly Shape Empty = new EmptyShape();private class EmptyShape : Shape{}}

    代码范例:

    public static string CooperationNameVFP = "VFP枚举映射";

    改成:

    public const string CooperationNameVFP = "VFP枚举映射";

    Instance members should not write to "static" fields

    规则:

    Correctly updating a static field from a non-static method istricky to get right and could easily lead to bugs if there are
    multipleclass instances and/or multiple threads in play.This rule raises an issue each time a static field is updated from a
    non-static method or property.Noncompliant Code Examplepublic class MyClass{private static int count = 0;public void DoSomething(){//...count++; // Noncompliant}}

    Remove the exception throwing from this property getter, or refactor the property into a method

    代码范例:

    /// <summary>/// 获取重定向的URl/// </summary>public string RedirectUrl{
        get
        {
            try
            {
                if (Header != null && Header.Count > 0 && Header.AllKeys.Any(k => k.ToLower(CultureInfo.CurrentCulture).Contains("location")))
                {
                    string locationurl = Header["location"].ToString().ToLower(CultureInfo.CurrentCulture);
    
                    if (!string.IsNullOrWhiteSpace(locationurl))
                    {
                        return (locationurl.StartsWith("http://") || locationurl.StartsWith("https://")) ? string.Empty : new Uri(new Uri(ResponseUri), locationurl).AbsoluteUri;
                    }
                    return locationurl;
                }
            }
            catch
            {
                throw;
            }
            return string.Empty;
        }}



    标签: 代码检查 sonar_
    分类: 代码健康

    有话要说? =>【不用注册,直接登录】,然后刷新本页面来发表您的观点(●'◡'●)