I really think that either SPBaseCollection (from which SPWebCollection,SPFolderFollection and SPFileCollection) included a Contains feature. Preferably a containsKey feature.
This article will present a method for quickly establishing if any of the
3 classes contain an object with a specific name.
First some background:
SPBaseCollection derives from ICollection, which unfortunately does not contain a definition for Contains. The new ICollection<T> generic interface does contain a definition for it though. so Microsoft did learn.
SPBaseCollection is the base class for almost all the Sharepoint collections (a list is here), and a contains method that is based on the name, such as the indexers in SPFolder,SPFile and SPWeb collection might not lend itself to all of them. A second base class that classes that shared a string indexer would be beneficial.
If I was working on a project with C# 3.0 I could have used the new feature of extension methods to inject a contains into the collections I work with, but since I am stuck with C# 2.0 that wont work.
I have seen a lot of code, and even written some code for Sharepoint that looks through the entire collection for a specific entry.
In fact if Sharepoint had been upgraded with 3.0 and Linq, I could perhaps write Linq queries to access the objects I wanted.
Instead of this:
foreach (SPList list in web.Lists)
{
if (list.BaseType == SPBaseType.DocumentLibrary)
{
lists.Add(list);
}
}
Linq could rescue me.
The goal for this article though is much simpler. I don't wish to have to iterate over SPWebCollection with a foreach looking for a specific site by name.
SPWebCollection does have an indexer that takes a string, that contains the name, but not a lookup like Contains.
I had expected that the indexer would throw an exception if I queried it with a non existent site. I didn't wish to incur the cost of an exception.
Testing however shows that SPFolderCollection,SPFileCollection and SPWebCollection all implement the string indexer and none of them throw an exception if queried with a non existent name.
Instead they return a an object of the type that the collection represents, but the collections property .Exists is set to false. Its basically an empty object.
This allows a syntax such as collection[name].Exists to be used, and it will not throw a nullException.
I created the following set of functions, because I like the explicit syntax of the methods, but its certainly less verbose to just invoke the Exists directly .
public static bool doesSPWebCollectionContainName(SPWebCollection collection, string name)
{
return collection[name].Exists;
}
public static bool doesSPFileCollectionContainName(SPFileCollection collection, string name)
{
return collection[name].Exists;
}
public static bool doesSPFolderCollectionContainName(SPFolderCollection collection, string name)
{
return collection[name].Exists;
}
Either way it is certainly better than iterating over the collection looking for a specific entry.
UPDATE:
It seems that even though everything should run fine according to the API, when it comes to SPFile and SPFolder they function in a different manner than expected as compared to SPWeb.
Ufortunatly SPFileCollection and SPFolderCollection seems to throw an Exception when the indexer tries to access a non existing entity. SPWeb doesnt. These work, but it involves the much dreaded Exception.
public static bool doesSPFileCollectionContainName(SPFileCollection collection, string name)
{
try
{
return collection[name].Exists;
}
catch (Exception )
{
return false;
}
}
public static bool doesSPFolderCollectionContainName(SPFolderCollection collection, string name)
{
try
{
return collection[name].Exists;
}
catch (Exception )
{
return false;
}
}