Wednesday 16 January 2008

SPFieldCollection indexer (Field[string]) Vs SPFieldCollection. GetField(string)

The Question can be asked don’t they do the same thing and reading the SDK doesn’t clear that up (see http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.spfieldcollection.aspx )
So a bit of work with Reflector and the difference becomes apparent

The Indexer calls the internal method GetFieldByDisplayName(strDisplayName, true)
Which in turn accesses the Display Name Hashtable using the parameter as the key value DisplayNameDict[strDisplayName];
(Note the second Pramater of GetFieldByDisplayName is a bool which sets if the method will throw any exceptions)
GetField(string) calls GetField(strName, true) which in turn will call GetFieldByInternalName(strName, false) which accesses the Internal Name Hashtable using the parameter as the key value InternalNameDict[strName] if this fails to return a value it accesses the InternalNameWithPrefixDict Hashtable. If GetFieldByInternalName fails to return a value GetField will make a call to GetFieldByDisplayName(strName, false)

In practice how does this help
The Indexer only works with Display Names while the GetField() will look for the internal name first but if it can’t find a field it will then try the parameter as the display name. This matches up nicely with the ContainsField(string) method as this method will return true if the string is found as ether a display name or a internal name. Using this we have a nice way of avoiding unnecessary exception handling when accessing List data

Eg
if (item.Fields.ContainsField(_fieldName))
{
holderstring = item[_fieldName].ToString();
}

Not checking to see if the field exists can cause a System.NullReferenceException - Object reference not set to an instance of an object on the ToString() method

Note there is also a GetFieldByInternalName(string) which will only call GetFieldByInternalName(strName, false)

No comments: