简体   繁体   中英

VS2010 Code Analysis and CA1800 : Microsoft Performance

I have the code below which I know isn't optimal. I ran the Code Analysis and it gave me the warning

CA1800 : Microsoft.Performance : 'customField', a variable, is cast to type 'DateCustomFieldRef' multiple times in method 'Customer.CustomerToUpdat(SearchResult)'. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant castclass instruction. 

and I really don't understand what to do.

CustomFieldRef[] customFields = customer.customFieldList;
for (int f = 3; f < customFields.Length; f++)
{
    CustomFieldRef customField = customFields[f];
    if (customField is DateCustomFieldRef)
        {
            DateCustomFieldRef dateField = (DateCustomFieldRef)customField;
                if (dateField.internalId != null && dateField.internalId == "created_date")
                    {
                            createdDate = dateField.value.ToString();
                        }
                }
                if (customField is StringCustomFieldRef)
                {
                    StringCustomFieldRef tradingNameField = (StringCustomFieldRef)customField;
                        if (businessNameField.internalId != null && businessNameField.internalId == "business_name")
                        {
                            businessName = businessNameField.value;
                    }
                }
        }
}

Could someone please give me a code example or explain further what it really means?

Thanks in advance.

The problem is in code like:

if (customField is DateCustomFieldRef)
{
  DateCustomFieldRef dateField = (DateCustomFieldRef)customField;

These are multiple casts.

Better:

DateCustomFieldRef fieldasDate = customField as DateCustomFieldFRef

if (fieldasDate != null)
{
  blablabla using fieldasdate

This avoids the multiple casts.

It means that you're casting (which can be costly) the customField variable multiple times, and that you'd be better of by casting only once.

You can use the as operator to achieve that, since the as operator performs the cast and returns an instance of the desired type, or NULL if the object could not be casted to the desired type.

Like this:

DateCustomFieldRef customField = customFields[f] as DateCustomFieldRef; // the as operator returns null if the casting did not succeed (that is, customFields[f] is not a DatecustomFieldRef instance

if (customField != null)
{
     DateCustomFieldRef dateField = customField;
     if (dateField.internalId != null && dateField.internalId == "created_date")
     {
           createdDate = dateField.value.ToString();
     }
}
else
{
    var stringField = customFields[f] as StringCustomFieldRef;
    if (stringField != null )
    {
        StringCustomFieldRef tradingNameField = stringField;
        if (businessNameField.internalId != null && businessNameField.internalId == "business_name")
        {
            businessName = businessNameField.value;
        }
    }
}

But, I believe that there probably exists an even better solution (although I do not know your project, nor your code), but wouldn't it be possible to abstract some things away ?

Perhaps you have a CustomField baseclass, and DateCustomFieldRef and StringCustomFieldRef inherit from that Customfield base-class. If that's the case, you could create a virtual (or maybe even abstract) method in the CustomField base-class, which is overriden in each child-class, which actually returns the value of that field.

Like this:

public class CustomField<T>
{

    public string Internalid
    {
        get;
        set;
    }

    public T Value
    { 
        get;
        set;
    }

    public virtual string GetStringRepresentation()
    {
        return Value.ToString();
    }
}

public class DateCustomField : CustomField<DateTime>
{
    public override string GetStringRepresentation()
    {
         return Value.ToShortDateString();
    }
}

Your code can then look much more simple:

foreach( CustomField f in customFields )
{
     if( f.InternalId == "created_date" )
     {
         createdDate = f.GetStringRepresentation();
     }
     if( f.InternalId == "business_name" )
     {
         businessName = f.GetStringRepresentation();
     }
}

(The code above could be made more simple and clean, but you'll get the drift.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM