How to minimize the overhead by implementing an Array Wrapper?
1 Which Interface/Type to choose for MyProviderInfos?
2 Is that reasonable to use private static enumerator? NO, from the
answer
3 Should MyProviderInfos be a property and how to protect its members from modifications? internal/private SETTERS for members (from the same answer)
I tried going through SO articles about ICollection, Readonly-Collection, List, IList, Array, but still confused what would be best for the scenario:
- The Array MyProviderInfos is formed by the compile time and will not (must not) be changed at the run-time.
- The Class is (must be) Enumerable (with Elements of the Array MyProviderInfos) and Custom List functions (.Add .Remove) are NOT necessary.
- The class HAS static functions, which use the Array.
- The class MUST be non-static to support Indexing.
Code:
public class MyIdentifiers : IEnumerable<MyProviderInfo>
{
//public static IList<MyProviderInfo> getMyProviderInfos()
//{ return MyProviderInfos; }
public static int MyProviderCount()
{
return MyProviderInfos.Count;
}
public static readonly IList<MyProviderInfo> MyProviderInfos = new[]
{
new MyProviderInfo
{
MyProvider = MyProvider.FirstProvider,
Url = "https://www.google.com",
}
};
private static IEnumerator<MyProviderInfo> _enumerator =
((IEnumerable<MyProviderInfo>)MyProviderInfos).GetEnumerator();
public IEnumerator<MyProviderInfo> GetEnumerator()
{
return _enumerator;
//return ((IEnumerable<MyProviderInfo>)MyProviderInfos).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Unless you want to limit features directly visible to your users you should always return the less generic type (in your case the array itself).
As general rule it’s a good practice to accept the most generic possible type as parameter (for example if you just want to enumerate a collection then declare that parameter as
IEnumerable<T>) and the less generic as result (so users can use it asIEnumerable<T>if they just need that or asIList<T>, as needed, without fragile casts and conversions). Moreover, in your case,IList<T>supports adding items but this will throw at run-time because array is fixed size so you expose more than what they actually can do.For example:
Of course you can return an
IEnumerable<string>too instead ofstring[], it may be appropriate if – for example – the implementation doesn’t create any array for the result to avoid an extra conversion.Absolutely no, an enumerator is an object with a state (take a look to any
IEnumerator<T>implementation) then it can’t be static (imagine when called by different threads, for example).It doesn’t need to be a property unless you want to provide some kind of lazy initialization. To protect its members the only thing you can do is to make them read-only (it doesn’t matter if the collection itself is read-only). How to do it depends on
MyProviderInfoimplementation. You may consider to do not expose anypublicsetter for its properties. For example:Or, without too many changes, keep your existing code but make setters internal (so users of your library won’t be able to modify them):
To summarize a little bit I would rewrite that as this: