All, I have an application that needs to attach and detach multiple SQL databases regularly. I want to create a class that holds all of these databases as a collection that can be iterated over. To do this I am inheriting from ICollection, but there is some thinkg I am not understanding:
class SqlDataBases : ICollection<SqlDb>
{
private List<SqlDb> dbColl;
public SqlDataBases()
{
dbColl = new List<SqlDb>();
}
// Add an index to the collection.
public SqlDb this[int _nIndex]
{
get { return (SqlDb)dbColl[_nIndex]; }
set { dbColl[_nIndex] = value; }
}
// et al.
}
public class DbEnumerator : IEnumerator<SqlDb>
{
// ...
}
class SqlDb
{
private string strMdfFullPath;
private string strLdfFullPath;
private bool bIsAttached;
public SqlDb(string _strMdfFullPath, string _strLdfFullPath, bool _bIsAttached)
{
this.strMdfFullPath = _strMdfFullPath;
this.strLdfFullPath = _strLdfFullPath;
this.bIsAttached = _bIsAttached;
}
}
My question is "why inherit from ICollection at all, when you have to add methods such as 'Add', 'Contains' etc. yourself? Or do you have to do this yourself as suggested in MSDN? I have been reading "C# in a Nutshell" and this question is something that stands out unaddressed in this great book.
I apologise, I know I am missing something here...
My question is "why inherit from ICollection at all, when you have to add methods such as 'Add', 'Contains' etc. yourself?
ICollection<T> is an interface - it just specifies the members that you have to implement. If you want to derive from something which already has an implementation, look at Collection<T>. You would implement the interface yourself if you wanted to create your own collection data structure with its own special characteristics - I doubt that you want to do that.
To be honest, it's not clear why you want your own class here at all - why not just use List<SqlDb> in the client code directly?
Have you thought about using List<SqlDb> directly?
It's not obvious to me what you hope to gain by the SqlDataBases class.
If you can't use List<SqlDb> directly, think about inheriting from List<SqlDb> rather than ICollection<SqlDb>.
Interfaces are only skeletons. They aren't containing any logic, they are containing only the signatures of all method, property etc.
Interfaces
The reason to inherit from ICollection<> is to create your own custom collection type. Then, anywhere a method has an input variable of ICollection<>, because you inherited from ICollection<>, your new custom collection type can be passed in.
In your case, you could simply use List<> until you find a need to create a custom collection.
Answering "why inherit from ICollection at all, when you have to add methods such as 'Add'":
you don't need to inherit ICollection if you don't need/want to have Add/Next etc.
Related
I have a class, which holds some details in a large data structure, accepts an algorithm to perform some calculations on it, has methods to validate inputs to the data structure.
But then I would like to return the data structure, so that it can be transformed into various output forms (string / C# DataTable / custom file output) by the View Model.
class MyProductsCollection {
private IDictionary<string, IDictionary<int, ISet<Period>>> products;
// ctors, verify input, add and run_algorithm methods
}
I know that you are supposed to use the "depend on interface not implementation" design principle, so I want to create an interface for the class.
How can I avoid writing the following interface?
Reason being it would expose implementation details and bind any other concrete implementations to return the same form.
interface IProductsCollection {
IDictionary<string, IDictionary<int, ISet<IPeriod>>> GetData();
// other methods
}
How can I easily iterate over the data structure to form different varieties of outputs without bluntly exposing it like this?
EDIT:
Since the class takes in IFunc<IDictionary<string, IDictionary<int, ISet<IPeriod>>>> in the constructor to iterate over the data structure and perform calculations, I could supply it with another IFunc, which would construct the output instead of running calculations. However, I don't know how I could do this aside from the concrete class constructor.
The structure of the IDictionary<string,IDictionary<int,ISet<Period>>> is very suspicious indeed - when you see a dictionary of dictionaries, good chances are that you have missed an opportunity or two to create a class to encapsulate the inner dictionary.
Without knowing much of the domain of your problem, I would suggest defining an interface to encapsulate the inner dictionary. It looks like something that associates a number to a set of periods, so you would define an interface like this:
interface IYearlyPeriods {
bool HasPeriodsForYear(int year);
ISet<Periond> GetPeriodsForYear(int year);
}
I have no idea what's in the periods, so you would need to choose a domain-specific name for the interface.
Moreover, you can wrap the next level of IDictionary too:
interface IProductDataSource {
IEnumerable<string> ProductNames { get; }
IYearlyPeriods GetProductData(string productName);
}
Now you can define an interface like this:
interface IProductsCollection {
IProductDataSource GetDataSource();
// other methods
}
The main idea is to use domain-specific interfaces in place of generic collections, so that the readers and implementers of your code would have some idea of what's inside without referring to the documentation.
You could go even further, and replace the IDictionary with the complex structure that you keep internally with an IDictionary of IProductPeriods implementation. If you would like to keep IYearlyPeriods that you expose to the users immutable, but would like to be able to make modifications yourself, you can make a mutable implementation, and keep it internal to the implementing class.
I would suggest to keep the IDictionary private and provide a simple IEnumerable in the interface.
In your case this could be a custom DTO that hides all the nastiness of the IDictionary<int, ISet<IPeriod>> - which is already quite complex and could (probably) easily change as you need to implement new features.
This could be something like:
class ExposedPeriod
{
public int PeriodIdentifier { get; set; }
public IEnumerable<IPeriod> Periods { get; set; }
}
The ExposedPeriod and PeriodIdentifier probably need better names though. Good names might be found in your domain vocabulary.
I've got several C# classes each with similar properties.
(They're part of an SDK and their code can’t be changed.)
Person.Name
Product.Name
Order.Name
I want to use these classes polymorphically, but they don’t implement a common interface or derive from a common base class, so that’s not possible.
To get around this, I’d like to wrap each one in another class that does implement a common interface, and wire-up each class property to its corresponding interface property.
What would be a suitable name for the wrapper classes? Wrapper, Decorator, Adaptor, Proxy? Does this pattern have a name? Is there a better approach?
(I don't want to use dynamic duck-typing or an impromptu interface.)
It looks like Adapter, because you are adapting the existing interfaces to the specific requirements.
(I don't want to use dynamic duck-typing or an impromptu interface.)
So what is wrong with a NamedObject?
public class NamedObject
{
public string Name { get; set; }
}
It literally says what it is, nothing less, nothing more.
I'd stick with CodeCaster's idea, and perhaps with a dash of Func<T> for no other reason than I get withdrawal symptoms when I don't use angle brackets...
public class NamedEntity
{
public string Name { get { return _getName(); } }
private Func<string> _getName;
public NamedObject(Func<string> getName)
{
_getName = getName;
}
}
And then call thus:
var named = new[]
{
new NamedEntity(() => person.Name),
new NamedEntity(() => product.Name),
new NamedEntity(() => order.Name)
};
The added benefit with this is when the value of the property changes on the target object, it changes within the NamedEntity reference too via the Func, this means within the life span of the objects you can get away with wrapping them once. You can also do the inverse with Funcs that set values as well as get, and can adapt more properties.
I am not immediately sure what pattern this represents (if any), though I would guess Adapter pattern (which is a type of wrapper pattern). However, it could also be argued to be a Proxy pattern. Not sure really.
Maybe you can just change the namespace and keep the names of the original classes.
Technically, I think the most correct name would be Adapter, see this question.
Adapter is used when you have an abstract interface, and you want to map that interface to another object which has similar functional role, but a different interface.
You don't have abstract interface, but "similar functional role, but a different interface".
I have a class:
public class MyClass {
private List<string> folderList;
// .... a lot of useful public methods here.....
}
Everything is fine. The list of folders is encapsulated, the class is accessible through public methods. OK. Now I need an "options" form that allows a user to choose folders for MyClass. There is a catch: new Setup class must have access to private folderList field (or I have to provide public methods to get and set the folder list - it's essentially the same). In old good C++ I would use 'friend' feature because nobody but Setup class may access folderList. But there is no 'friend' feature in C# (I'm a newbie in the C# world).
P.S. Actually I just made folderList public, but I feel there is a better solution.
Thanks.
You can use "internal" keyword to make your method available only within your assembly/project and if you want to access your internal methods in other project or assembly then you can use "InternalsVisibleTo" attribute, where you can access your internals only in that assembly for which you define this attribute.
MSDN Internal Keyword
I believe the keyword you're looking for is internal. It is loosely equivilent to C++'s friend.
Internal provides assembly-level visibility.
Paired with Femaref's suggestion of using a Property, and you should have your full solution.
I am not sure if this is what he/she wanted. He/she did not put the requirement that the potential client will be in current assembly... Accordingly, when using friend in c++ (which was never considered a good style) you must know the exact type of the class which will be entitled to access the member. If this class is not part of the program you are writing, you cannot grant access this way.
If you want conditional access to some property or method of an instance of a class, you will need to implement some kind of entitlement mechanism, for example:
public IList<Folder> GetFolderList(Object pClient, IEntitlementService pService) {
if (pService.IsEntitledToAccess(this, pClient) {
return folderList;
} else {
throw new AccessNotGrantedException("...");
}
}
I believe there are built-in utilities in the .Net framwork for that purpose, just go and google (or bing)...
As an exact answer to the question I would suggest the following - create a separate interface IFolderList:
interface IFolderList
{
IList<string> FolderList { get; }
...
}
Well, you can add other required members to interface
In the class MyClass implement this interface explicitly.
As a result, the class Setup can gain access to data through an explicit cast to an interface IFolderList or work only with these interface.
An alternative to making an internal method to be used by your Setup class would be to use the Visitor pattern and add a method that takes a Setup class instance as a parameter, then uses the private folderList to initialize/change Setup state as required. Of course that would require the appropriate public methods on the Setup class, so might not fit your needs.
Making folderList field public is the worst case. Exposing implementation details through public fields or through poorly designed public property (there are no differences for collections between public fields and public property with getter and setter).
With public fields you can't promote a field to be a property when you want to add validation, change notification, put it into an interface or change your collection type from one type to another.
BTW, Jeffrey Richter in annotation to Framework Design Guideline mentioned that "Personally, I always make my fields private. I don't even expose fields as internal, because doing so would give me no protection from code in my own assembly"
I think the best way to add explicit interface that expose strict abstraction to MyClass clients.
For example, you may add two separate methods to retrieving folders and to adding new folder to this storage:
class MyClass {
//You should return IList<string>
public IList<string> MyList {get {return myList;} }
//Or even IEnumerable<string>, because you should return
//as minimal interface as your clients needs
public IEnumerable<string> MyList {get {return myList;} }
//You may expose this functionality through internal
//method, or through protected internal method,
//but you should avoid direct access to your implementation
//even for descendants or another classes in your assembly
public void AddElement(string s) {myList.Add(s);}
private List<string> myList;
}
That's what properties are for in C#:
public class MyClass
{
private List folderList;
public List FolderList
{
get {return folderList;}
set {folderList = value;}
}
}
Properties encapsulate the private fields, provide possibilites for validation while setting. Also, you should read up on Generics (abit like templates in c++) and use List<T> instead of List to have a strongly typed collection.
However, you probably wont be able to achieve what you plan unless Setup derives from MyClass. In that case, you can use a protected field.
This question already has answers here:
Why/when should you use nested classes in .net? Or shouldn't you?
(14 answers)
Closed 10 years ago.
Specifically, can anyone give me concrete examples of when or when not to use nested classes?
I've known about this feature since forever, but never had a reason to use it.
Thanks.
When the nested class is only used by the outer class, a great example, no longer necessary, is for an enumerator class for a collection.
another example might be for a enum to replace a true false parameter used by a method within a class, to clarify the call signature...
instead of
public class Product
{
public void AmountInInventory(int warehouseId, bool includeReturns)
{
int totalCount = CountOfNewItems();
if (includeReturns)
totalCount+= CountOfReturnedItems();
return totalCount;
}
}
and
product P = new Product();
int TotalInventory = P.AmountInInventory(123, true);
which leaves it unclear as to what 'true' means, you could write:
public class Product
{
[Flags]public enum Include{None=0, New=1, Returns=2, All=3 }
public void AmountInInventory(int warehouseId, Include include)
{
int totalCount = 0;
if ((include & Include.New) == Include.New)
totalCount += CountOfNewItems();
if ((include & Include.Returns) == Include.Returns)
totalCount += CountOfReturns();
return totalCount;
}
}
product P = new Product();
int TotalInventory = P.AmountInInventory(123, Product.Include.All);
Which makes the parameter value clear in client code.
The two places where I use nested classes:
The nested class is used exclusively by the outer class, and I want completely private scope.
The nested class is used specifically to implement an interface defined elsewhere. For example, implementing an enumerator falls into this category.
You really only want to use nested classes when you are sure the nested class doesn't make sense that it would be used anywhere else.
For example, if you needed to create a list of several types of object associated together with functions and member information about that set of objects for a short time (like methods or properties), you could use a nested class to do that. Maybe you need to create a list of all combinations of some type of object, and then mark all combinations that have a certain property. That would be a good case for a nested class.
If you don't need methods on the nested class, you can probably just use a struct but I don't know if IL treats them any differently.
I sometimes use this for simple helper classes that I need for a function or two inside of the parent class.
For a practical example, see this question asked earlier this morning:
Make an object accessible to only one other object in the same assembly?
Summary: you can nest an associated data class inside it's business object.
I've seen cases of nested classes when a special purpose data structure is used only within one class, or a certain exception is thrown and caught only within one class.
I nest classes when I have a helper class which has no need to be visible to any other object in the system. This keeps the visibility as constrained as possible which helps prevent unintended uses of the class
Following Uncle Bob's 'rules' on cohesion should find that you actually create quite a number of nested (and nested, nested!) classes. These could be made non-nested but only if you have other clients that reference them now.
I'd like to improve on my previous answer!
A specific area where I use nested classes regularly is enabling Interface Injection and Inversion of Control. Example...
public class Worker
{
private IHelper _helper;
public Worker()
: this (new DefaultHelper())
{
}
public Worker(IHelper helper)
{
this._helper = helper;
}
private class DefaultHelper : IHelper
{
}
}
Lets say I inherit a class, that has several public properties and/or methods, however I do not want them to be public properties/methods of my class - in other words, I want to make those properties protected properties of my class.
Can this be achieved?
I hope I was clear enough, if not please let me know, will try to explain myself better.
EDIT:
Right, thank you all for answers however I don't think I was clear enough. What I am trying to accomplish is this:
I wrote a windows control that extends ListView control. ListView has a public collection Items, that can be modified. That's all fine, however I wrote new methods for adding items to listview because of the extra data I need.
It all works great so far, however the Items collection can still be modified by anything, which is a problem, because if an item is added by direct manipulation of Items collection not all data I need is gathered, thus causing an error.
Since we hope to reuse this control several times in different projects, we are afraid that sooner or later, the default way of adding items to Items collection will be used (just a matter of time really). We are just looking for a way to prevent that from happening, like throwing an exception when Items collection gets bigger, but the way it was intended.
I hope this all makes sense now.
Never say never. This is probably not the best idea but it seems to work for me. This hides items by re-implementing it in the subclass and then hiding it using attributes. I added in a "CustomExposedItems" property so you can see that the existing items are still accessible in the underlying ListView.
public partial class CustomListView : ListView
{
public CustomListView()
{
InitializeComponent();
}
public System.Windows.Forms.ListView.ListViewItemCollection CustomExposedItems
{
get
{
return base.Items;
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("Use the new custom way of adding items xyz")]
public new System.Windows.Forms.ListView.ListViewItemCollection Items
{
get { throw new NotSupportedException(); }
}
}
Inheritance is all about saying "You can use this derived class in the same way as you can use the base class, and it provides specialized behaviour."
If you can't use the derived class in the same way as the base class, then you shouldn't be using inheritance: you're breaking Liskov's Substitutability Principle. In such a case, use composition instead of inheritance. (Personally I don't use class-to-class inheritance that much anyway, far preferring composition - I find there are relatively few cases where the specialization aspect really works without issues. When it does work it's great though!)
No, you cannot do that. The best you can do is creating a class and wrap the base class insted of deriving from it - but this will of course break inheritance. (I assume you cannot modify the base class. If you can, you should rethink the design because it looks like your new class should not derive from the base class.)
class BaseClass
{
public String IWantThis { get; set; }
public String IDoNotWantThis { get; set; }
}
class MyClass
{
private BaseClass baseClass = new BaseClass();
public String IWantThis
{
get { return this.baseClass.IWantThis; }
set { this.baseClass.IWantThis = value; }
}
}
You can't do this by inheritance. This is actually what inheritance is about. An is-a relation cannot reduce the interface. The derived class must be a full representation of the base class.
Turn your inheritance into a reference. You reuse the implementation of your "base class" by calling it. (Composition instead of inheritance.) If you need polymorphism, add a common interface or move the common part into a separate abstract base class.
I not use AOP, perhaps PostSharp, to put around the Property you don't want used, and then you can handle it in some appropriate fashion with your aspect.