Interface Segregation Principle on a collection of objects - c#

I am studying on the SOLID principles and the interface segregation principle is giving me a hard time to understand in a scenario like this one.
Basically, I have a collection of objects... users... that use an interface.
public interface IUserInfo
{
string Name { get; }
string Extension { get; }
}
The issue is that there are some cases where a class that inherits this interface will not use an extension. So to get around that, it simply returns an empty string.
Now, technically this is fine because the string is bound to the UI. So it would simply display an empty string for that field.
However, this violates the Interface Segregation Principle. What is suggested is to split those interfaces.
But then I run into problems where I want this interface in a collection, consider this:
public interface IUserExtension : IUserInfo
{
string Extension { get; }
}
public ObservableCollection<IUserInfo> StoredUserInfos { get; set; } = new ObservableCollection<IUserInfo>()
{
new User1(),
new User2(),
};
public class User1 : IUserExtension
{
public string Name { get; } = "Alex";
public string Extension { get; } = "(715) 925";
public override string ToString()
{
return Name;
}
}
public class User2 : IUserInfo
{
public string Name { get; } = "Daniel";
public override string ToString()
{
return Name;
}
}
I cant bind to the index of this collection and obtain the Extension, because it is an IUserInfo interface. Coincidentally, I also cannot make this a collection of IUserExtension because the User2 class doesn't implement it.
The only way for this to work would be to use pattern matching as far as I am aware
if (UserIndex != -1)
{
var userInfo = StoredUserInfos[UserIndex];
Extension = userInfo is IUserExtension info ? info.Extension : "No Extensions";
Name = userInfo.Name;
}
But that adds a bit of complexity to the code and it may violate other rules because it is checking for the type.
In this case, would the best solution instead would be to implement an abstract class that implements the interface and the default implementation would be an empty string?

This is a difficult one, but I'm going to stick my neck out and attempt to answer.
Does including Extension in the IUserInfo interface violate ISP? I think yes and no.
Let's imagine you want to include a MiddleName property in your IUserInfo interface. A middle name is something that not everyone has but you probably wouldn't want to add that to a separate interface. Along with the Name property, they are a cohesive unit, i.e. they belong together.
In this case, you would probably want to return an empty string (as you have above) or such like. (For more complicated objects with behaviour the Null Object pattern is a much better solution.)
So if we return to your problem above, do you see Extension as something that belongs in an interface on its own? Probably not. Again, let's imagine adding EmailAddress to the IUserInfo interface. Along with Extension, they make a cohesive unit and conceptually represent contact details. If you were to extract these into a separate interface, you would still have some users that do not have an extension in which case you would want to return an empty string (or similar).
So, in answer to your question, I think you could keep Extension in the IUserInfo interface if you are unlikely to extend the interface with any more properties. Otherwise, create an interface that represents the concept of contact details but still returns an empty string if the user doesn't have an extension.

Related

Ensure that all classes will share same method and fields

I my data access layer I want to use DTOs and make sure that all gateways (table data gateway) will implement method which return List of some DTO specific for given gateway.
To make this happen I have created empty interface like this
public interface IDataTransferObject{}
implemented this interface by all DTOs like this
public class UserAccountTypeDTO : IDataTransferObject
{
public int Id { get; set; }
public int AccountTitle { get; set; }
public int CreditTypeId { get; set; }
public bool Active { get; set; }
}
then I have made generic interface for all my gateways
public interface IDefaultGateway<D> where D:IDataTransferObject
{
List<D> Read(SqlDataReader sqlReader);
}
and finally implemented IDefaultGateway by my gateways
class UserAccountTypeGW : IDefaultGateway<UserAccountTypeDTO>
{
private const string Table = " UserAccountType ";
private string SelectAll = "select * from" + Table + "";
private string SelectById = ...;
public List<UserAccountTypeDTO> Read(SqlDataReader sqlReader)
{
throw new NotImplementedException();
}
}
Is it ok to make empty interfaces just to somehow group classes together even if they don't share any behavior?
Fields in gateways are the same only its values are changing. I did copy and paste for fields to each gateway and I would like to know whether there is faster/lazier way how to do this.
Interface and fields are not friends, therefore it could have been defined as properties. Since there is a need to create constructor in each DTO to initialize properties and also make set private it turns out to be little bit worse than what I did.
Abstract class was pretty much the same as interface
Create base class, define fields and methods and initialize (or override) them in gateway constructor is better in this case or pretty much the same as what have I done?
The word you need to search for is called Marker Interfaces. This is the guideline from MSDN:
AVOID using marker interfaces (interfaces with no members).
If you need to mark a class as having a specific characteristic (marker), in general, use a custom attribute rather than an interface.
Having said that, it is easier to check if a class implements an interface than to check if it has an attribute.
And as #Groo has mentioned in the comment section of this answer, which is a really good point:
Marker interfaces also at least give some compile-time checks, compared to attribute
Regarding the second part of the question (how to avoid code duplication), this is what abstract classes are for.
You can provide some default values which derived classes can override if needed:
abstract class BaseGateway<T> : IDefaultGateway<T> where T : IDataTransferObject
{
readonly string _tableName;
readonly string _selectAll;
public BaseGateway()
{
// default table name
_tableName = this.GetType().Name.Replace("DTO", "");
_selectAll = $"select * from {_tableName}";
}
// these members are virtual, so that they can be overriden
protected virtual string TableName => _tableName;
protected virtual string SelectAll => _selectAll;
// derived classes should implement their own 'Read' method
public abstract List<T> Read(IDataReader sqlReader);
}
However, note that doing stuff like this makes your code prone to SQL injection attacks. It would be a better idea to use an ORM, or at least a "micro" ORM like Dapper.
Dapper gives you this simplicity in a couple of plain IDbConnection extension methods:
public class Dog
{
public int Age { get; set; }
public string Name { get; set; }
}
using (IDbConnection conn = OpenConnection())
{
var dog = conn
.Query<Dog>("Select * from Dog where Age = #Age", new { Age = 10 })
.FirstOrDefault();
}
Avoid using those marker interfaces. The only 'good' reason to use marker interfaces nowadays is if you plan to manipulate certain types of objects using reflection (and it's not a case this time).
In this case - abstract class seems to be the best choice. Define that Read() method inside the abstract class and properties with their default implementation. Override it with virtual method in all the descendants as needed. This way you won't even need a wrapper class for reading every specific type of object, as you will be able to reference that object and call Read() on it directly.

How to write a method that can be shared by two non-inherited class

I am having 2 classes, both having a same method(name + type +behavior) and a same property (name + type)
public class Country
{
public string Name { get; set; }
public void DisplayName()
{
Console.WriteLine(this.Name);
}
}
public class Person
{
public string Name { get; set; }
public void DisplayName()
{
Console.WriteLine(this.Name);
}
}
-- Person and Country classes are not allowed to inherit
In the above code you can see Person class has similar method(DisplayName) like Country class. I am looking for a way so that both classes can share the same method codes, i want to do this because in my real codes- Method which i want to share is very big and whenever i change code in one class i have to copy paste it in other class too. That i feel is not the correct way.
Please suggest how to resolve this problem.
You say they cannot inherit from a common base class, but you could add an interface, right? I suggest giving them each a common interface. Then define an extension method for that interface. The method will appear for each of them in VS.
(Assumption: this will work if the class members accessed by the extension methods are public or internal.)
interface IDisplayable
{
string Name {get; set;}
}
public class Country : IDisplayable
{
public string Name { get; set; }
}
public class Person : IDisplayable
{
public string Name { get; set; }
}
public static void DisplayName(this iDisplayable d)
{
return doSomeDisplayLogic(d.Name);
}
. . . And in the same class as your extension method, define (not as an extension method) a function doSomeDisplayLogic to do your common logic. (first-time gotcha: make sure the extension method is in the same Namespace or the its namespace is also included in the calling code.)
I don't know if you're new to extension methods or not. They are very powerful. (And like many powerful features, they can be abused). An extension method on an interface seems crazy at first, until you get straight in your head how extension methods really work. LINQ wouldn't work without this!
Update: I see your comment above that the classes can't inherit from a common class, because they are already inheriting from a common class (which I assume can't be messed with too much). I would like to point out an Option 2, based on this: Creating a new class that Country/Person/etc. will inherit from, that itself inherits from the existing common parent class. The existing base class would become a grandparent class, so to speak. This would become more the route to go if Country and Person have other common characteristics besides this DisplayName method. If DisplayName is all you're after, the Interface/Extension pattern might be better.
Define an interface
public interface INameable
{
string Name {get;}
}
then add an extension
public static class INameableExt
{
public static void DisplayName(this INameable n)
{
// do your thing
}
}
I would suggest to avoid Extension Methods in some cases, you can ran into a problem when you need slightly a different implementation for both classes and then you have to design a more generic solution, EM can cause the same issues like multiple inheritance does.
As more generic OOD solution I would suggest to extract this behaviour into a separate service class abstracted by an interface:
public interface IDisplayService()
{
void Display();
}
Then implement it and inject into both classes via constructor.
Also, instead of introducing the interfaces and new classes you can inject Action or Func<> via constructor or even property and then call this method by invoking an injected in delegate.
You could create either a static utility method DisplayName() that you pass the data needed for display, or use composition and move all properties and corresponding methods such as DisplayName() in a separate class - then use an instance of this class from both Country and Person.
You could implement a strategy pattern:
class DisplayNameStrategy<T> {
private readonly Func<T, string> nameSelector;
public void DisplayNameStrategy(Func<T, string> nameSelector) {
this.nameSelector = nameSelector;
}
public void abstract DisplayName(T t);
}
class WriteToConsoleDisplayNameStrategy<T> : DisplayNameStrategy<T> {
public void WriteToConsoleDisplayNameStrategy(Func<T, string> nameSelector)
: base(nameSelector) { }
public override void DisplayName(T t) {
Console.WriteLine(this.nameSelector(t));
}
public class Person {
private readonly DisplayNameStrategy<Person> displayNameStrategy =
new WriteToConsoleDisplayNameStrategy<Person>(x => x.Name);
public string Name { get; set; }
public void DisplayName() {
this.displayNameStrategy(this);
}
}
Note: it's probably better to inject the concrete strategy.
You could use composition: define an interface, a class that implements it, and then have Person and Country implement the interface by calling methods on the implementation class:
// the interface
public interface IName {
string Name { get; set; }
void DisplayName();
}
// a class that implements the interface with actual code
public class NameImpl : IName {
public string Name { get; set; }
public void DisplayName() {
Console.WriteLine(this.Name);
}
}
public class Country : IName {
// instance of the class that actually implements the interface
IName iname = new NameImpl();
// forward calls to implementation
public string Name {
get { return iname.Name; }
set { iname.Name = value; }
}
public void DisplayName() {
// forward calls to implementation
iname.DisplayName();
}
}
What I THINK you are asking for is multiple class inheritance which is not allowed in C#. (but can be with C++ which you are NOT doing).
All the others have identified doing an INTERFACE solution, and probably the best way to go. However, from your description, you have a SINGLE BLOCK of code that is identical regardless of the type of object being a person or a business. And your reference to a huge block of code, you don't want to copy/paste that same exact code among all the other classes that may be intended to use similar common "thing" to be done.
For simple example, you have a functionality that builds out a person's name and address (or business name and address). You have code that is expecting a name and up to 3 address lines, plus a city, state, zip code (or whatever else). So, the formatting of such name/address information is the same for a person vs a business. You don't want to copy this exact method over and over between the two. However, each individual class still has its own things that it is responsible for.
I know its a simple example for context, but I think gets the point across.
The problem with just defining an Interface is that it won't allow you to actually implement the CODE you are referring to.
From your sample, I would consider doing a combination of things.. Create a static class with methods on it that you might want as "globally" available. Allow a parameter to be passed into it of an instance of a class that has a type of interface all the others have expressed that will guarantee the incoming object has all the "pieces" of properties / methods you are expecting, and have IT operate on it as needed. Something like
public interface ITheyHaveInCommon
{
string Name;
string GetOtherValue();
int SomethingElse;
}
public class Person : ITheyHaveInCommon
{
// rest of your delcarations for the required contract elements
// of the ITheyHaveInCommon interface...
}
public class Country : ITheyHaveInCommon
{
// rest of your delcarations for the required contract elements
// of the ITheyHaveInCommon interface...
}
public static class MyGlobalFunctions
{
public static string CommonFunction1( ITheyHaveInCommon incomingParm )
{
// now, you can act on ANY type of control that uses the
// ITheyHaveInCommon interface...
string Test = incomingParm.Name
+ incomingParm.GetOtherValue()
+ incomingParm.SomethingElse.ToString();
// blah blah with whatever else is in your "huge" function
return Test;
}
}
warning: lots of untested code here, wild guessing mostly since i disagree with the base assumption "no inheritance".
something like this should help you. create a new static class and paste your code in here.
public static class Display
{
public static void DisplayName<T>(T obj)
{
if ((T is Person) || (T is Country) || (T is whateveryouwant))
{
//do stuff
}
}
}
in your classes, refactor ShowDisplayName() to call that with "this" as parameter.
...
public void DisplayName()
{
DisplayName(this);
}
...
I wonder why your classes are not allowed to inherit it from a base class, since that's imho the right-est way to solve this.
A couple of options:
Make both classes implement an interface for the common members (Name) and add an extension method for the behaviour (or just a normal static method)
Create methods which take an instance and a lambda exppession to access the comment members, e.g.
public static void Display<T>(T item, Func<T, string> nameGetter)
You'd then call it with (say)
DisplayHelper.Display(person, p => p.Name);
The interface solution is the cleaner one, but using a delegate is more flexible - you don't need to be able to change the classes involved, and you can cope with small variations (e.g. PersonName vs FooName vs Name)
You can define that big method in a separate class and then call the method in both the above classes. For a static method, you can call the method using classname.methodname() syntax.
For a non static method, you will have to do this:
classname obj=new classname();
obj.methodname();

Standard Methods vs Extensions Methods

Assuming the following domain entity :
public enum Role
{
User = 0,
Moderator = 1,
Administrator = 2
}
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public Role Role { get; set; }
}
I need to know if the user can perform "Edit" action. So i've 2 solutions :
Create a CanEdit method inside the User entity
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public Role Role { get; set; }
public bool CanEdit()
{
return Role == Role.Moderator || Role == Role.Administrator;
}
}
Create a CanEdit Extension Method for User type :
public static class UserExtensions
{
public static bool CanEdit(this User user)
{
return user.Role == Role.Moderator || user.Role == Role.Administrator;
}
}
Both solution works, but the question is WHEN use standard methods vs using Extensions methods ?
Extension methods are simply syntactic sugar for plain, ordinary static methods.
If you control the class structure, you should implement all the necessary functionality within the class. Where extension methods are really useful/necessary is if you don't own the class that you are trying to "extend."
For this example, I think you should put the logic inside the User class. It is a logical function of the user itself; consumers should be able to use the CanEdit() method without having to use or even know about the UserExtensions class.
I mostly agree with Aaronaught's answer, but consider this:
Maybe your CanEdit() method or other similar methods (business rules) might change more or less often or depend on some external factors. Or over time, you will have more and more such rules (for different concerns). In that case you might want to keep them in a different place, separated from the domain model to ensure that the domain model doesn't have too many different responsibilities and doesn't need to change very often.
Then, one way can be to implement them as extension methods, because this allows you to keep these business rules separate from your domain model (e.g. User class), but the method is still easily discoverable by users of the User class.
Another way to implement such business rules would be the specification pattern, where you implement each rule as a separate (specification-) class, e.g. demonstrated in this blog post.
There is very little point in using Extension methods for the sake of using them. If the method belongs to the class, use it there. Extension methods are for extending things, use them when you have no control over the class, or for giving functionality to an interface where the functionality should apply to all classes derived from that interface.
if you do not have direct access to the source code for the class you should use Extensions methods if you do have access to the source code i see no reason to not use a standard methods...
I agree with Aaronaught here: Implement your own logic the old-fashioned way. Static method might cause issues (missing using statement and the method seems to be "missing") lateron.
Something inherent to your model should be part of your classes.

How To Implement Shared Behavior Between Classes (Without Multiple Inheritance Of Course) in C#

UPDATE:
So pretty much everyone here has told me that I just need to start all over again on how I designed my classes (thank you folks for your excellent answers by the way!). Taking the hint, I started doing extensive reading on the strategy pattern. I want to create behavior classes (or strategy classes) that inherit from an abstract base class or classes. The Candidate class would then have properties w/ the different abstract base class/classes as the Type for the behaviors or strategies. maybe something like this:
public abstract class SalaryStrategy {
public abstract decimal Salary { get; set; }
public abstract decimal Min { get; set; }
public abstract decimal Mid { get; set; }
public decimal CompaRatio {
get {
if (this.Mid == 0) { return 0; }
else { return this.Salary / this.Mid; }
}
}
}
public class InternalCurrentSalaryStrategy {
public override decimal Salary { get; set; }
public override decimal Min {
get { return this.Salary * .25m; }
set { }
}
public override decimal Mid { get; set; }
}
public class Candidate {
public int Id { get; set; }
public string Name { get; set; }
public SalaryStrategy CurrentSalaryStrategy { get; set; }
}
public static void Main(string[] args) {
var internal = new Candidate();
internal.CurrentSalaryStrategy = new InternalCurrentSalaryStrategy();
var internalElp = new Candidate();
internalElp.CurrentSalaryStrategy = new InternalCurrentSalaryStrategy();
var elp = new Candidate();
// elp.CurrentSalaryStrategy can stay null cause it's not used for elps
}
Any comments or suggestions?
ORIGINAL Question:
I am trying to learn and become more proficient at design patterns and principles. I have am currently working on a design for few classes that has stumped me. Here's a very condensed version of the code:
public class Candidate {
public int Id { get; set; }
public string Comments { get; set; }
// lots more properties and behaviors...
}
public class InternalCandidate : Candidate {
public decimal CurrentMid { get; set; }
public decimal CurrentMax {
get { return this.CurrentMin * 1.3m;
}
// lots more properties and behaviors...
}
public class EntryLevelCandidate : Candidate {
public string Gpa { get; set; }
// lots more properties and behaviors...
}
public class InternalEntryLevelCandidate /* what do I inherit here??? */ {
// needs all of the properties and behaviors of
// EntryLevelCandidate but also needs the CurrentMin and
// CurrentMax (and possibly more) in InternalCandidate
}
The InternalEntryLevelCandidate class is primarily an EntryLevelCandidate but needs to share some of the implementations of InternalCandidate. I say implementations because I don't want the implementations to be different or repeated, otherwise I would use an interface for common contracts and have concrete implementations in each class. Some of the implementations of the InternalCandidate properties and behaviors need to be common or shared. I have read about C++ and Ruby mixins, which seem to be something similar to what I want to do. I also read this interesting blog post that discusses an idea for a behavior type where a class would be able to inherit multiple behaviors while still maintaining a single "is a" relationship: http://www.deftflux.net/blog/post/A-good-design-for-multiple-implementation-inheritance.aspx. This seems to convey what I am wanting. Can anyone give me some direction on how I can accomplish this using good design practices?
Immutable data value classes. If any properties in your various Candidate subclasses represent some kind of meaningful data value, create an immutable class for it, with the behaviors you need. Each of your distinct Candidate subclasses can then use the data type, but your code is still encapsulated in the data classes.
Extension methods. These could be overloaded to work with any classes.
I'd avoid the decorator pattern and stick with compiled/reflectable functionality.
Composition. Develop the unique behaviors in separate classes right away, and build your Candidate classes around them, rather than writing unique behaviors in your Candidate classes and trying to pull out their functionality for use in related classes later.
Depending on how you use the classes, you could also implement and make use of explicit and implicit conversion operators to a related type, so instead of reimplementing interfaces (which you wanted to avoid), you could actually cast your object into the type/implementation you need for whatever purpose.
Another thing I just thought of, related to that last paragraph, is to have a leasing system, where your class spawns and object of the appropriate type, allows it to be manipulated, then consumes it later to assimilate the updated information.
Here's a scholarly paper on the subject that I think is pretty interesting (PDF link).
But, I think you are trying to impose business logic in your generalizations. You happen to know that an InternalCandidate will never have his GPA looked at. But, an InternalCandidate certainly has a GPA. So, you have cracked out this strange guy called an InternalEntryLevelCandidate because you happen to know that you want to look at this guy's GPA. Architecturally, I think the EntryLevelCandidate is incorrect. I would add a "Level" concept to a Candidate and give him a GPA. It's up to the business logic to decide if they look at the GPA or not.
Edit: Also, Scott Meyers does a great job of dissecting this issue in his books.
Disclaimer:
In my experience needing multiple inheritance is the exception rather than the rule, careful design of class hierarchies can usually avoid needing this feature. I agree with JP that this requirement could be avoided in your sample.
Back to the question, there is no clean solution, however you have a few options:
Use extension methods, has the disadvantage that right click Resolve does not works, also some people really dislike these puppies.
Create an aggregate object that holds and instance of each class you want composited, re-implement stub methods that delegate.
Define an interface for each behavior and have the methods in the base check if this is IInterface before executing the behavior. (allows you to pull behavior definitions to the base)
Near duplicate:
Multiple inheritance in C#
I agree that inheritance doesn't seem to be the right thing here. I'm not sure that I know the perfect answer, but perhaps the Decorator pattern is appropriate.
Another, more esoteric idea is to think about aspect-oriented programming. You can do some pretty amazing things with aspects, but it's a very advanced topic that I still haven't mastered. The kind of folks who have are like Rikard Oberg and his Qi4J cohorts.
I'd just use the Delegation pattern. Ultimately I'd use an interface for each distinct piece of functionality, then have a concrete class as a delegate for each interface. Then your final classes just use the delegates they need and can inherit from multiple interfaces.
public class InternalEntryLevelCandidate : EntryLevelCandidate {
private InternalCandidate internalCandidateDelegate
= new InternalCandidate();
public decimal CurrentMid {
get { return internalCandidateDelegate.CurrentMid; }
set { internalCandidateDelegate.CurrentMid = value; }
}
public decimal CurrentMax {
get { return internalCandidateDelegate.CurrentMax }
}
}

"Public" nested classes or not

Suppose I have a class 'Application'. In order to be initialised it takes certain settings in the constructor. Let's also assume that the number of settings is so many that it's compelling to place them in a class of their own.
Compare the following two implementations of this scenario.
Implementation 1:
class Application
{
Application(ApplicationSettings settings)
{
//Do initialisation here
}
}
class ApplicationSettings
{
//Settings related methods and properties here
}
Implementation 2:
class Application
{
Application(Application.Settings settings)
{
//Do initialisation here
}
class Settings
{
//Settings related methods and properties here
}
}
To me, the second approach is very much preferable. It is more readable because it strongly emphasises the relation between the two classes. When I write code to instantiate Application class anywhere, the second approach is going to look prettier.
Now just imagine the Settings class itself in turn had some similarly "related" class and that class in turn did so too. Go only three such levels and the class naming gets out out of hand in the 'non-nested' case. If you nest, however, things still stay elegant.
Despite the above, I've read people saying on StackOverflow that nested classes are justified only if they're not visible to the outside world; that is if they are used only for the internal implementation of the containing class. The commonly cited objection is bloating the size of containing class's source file, but partial classes is the perfect solution for that problem.
My question is, why are we wary of the "publicly exposed" use of nested classes? Are there any other arguments against such use?
I think it's fine. This is basically the builder pattern, and using nested classes works pretty well. It also lets the builder access private members of the outer class, which can be very useful. For instance, you can have a Build method on the builder which calls a private constructor on the outer class which takes an instance of the builder:
public class Outer
{
private Outer(Builder builder)
{
// Copy stuff
}
public class Builder
{
public Outer Build()
{
return new Outer(this);
}
}
}
That ensures that the only way of building an instance of the outer class is via the builder.
I use a pattern very much like this in my C# port of Protocol Buffers.
You can use namespaces to relate things that are... related.
For example:
namespace Diner
{
public class Sandwich
{
public Sandwich(Filling filling) { }
}
public class Filling { }
}
The advantage of this over using classes as if they were namespaces is that you can optionally use using on the calling side to abbreviate things:
using Diner;
...
var sandwich = new Sandwich(new Filling());
If you use the Sandwich class as if it were a namespace for Filling, you have to use the full name Sandwich.Filling to refer to Filling.
And how are you going to sleep at night knowing that?
You might want to check out what Microsoft has to say on the topic. Basically it's a question of style I'd say.
Another practical example that I have for a valid use of public nested classes is in MVC pattern when I use a viewmodel with an IEnumerable property. for example:
public class OrderViewModel
{
public int OrderId{ get; set; }
public IEnumerable<Product> Products{ get; set; }
public class Product {
public string ProductName{ get; set; }
public decimal ProductPrice{ get; set; }
}
}
I use it because I don't want Product class to be re-used outside because it is customized only for that specific viewmodel which contains it. But I can't make it private because the Products property is public.
I primarily use nested classes for fine-tuning access to the nested and/or the container class.
One thing to remember is that a nested class definition is basically a class member, and will have access to all the container's private variables.
You can also use this to control usage of a specific class.
Example:
public abstract class Outer
{
protected class Inner
{
}
}
Now, in this case, the user (of your class) can only access the Inner class, if he implements Outer.
I don't know if this is considered bad design or not, but I've got some search classes I make where a user calls the Run() method, passing in an object that holds search criteria. It then returns a collection of search result objects.
These SearchCriteria and SearchResult classes have no utility outside of using them with the Search class. So I nest them under the Search class to show they go together.
I have to make the nested classes public so the client of the Search class can make the SearchCriteria to pass into the Search class and so they can get the results of the Search.
public class PersonSearch
{
public PersonSearchCriteria
{
string FirstName {get; set;}
string LastName {get; set;}
}
public PersonSearchResult
{
string FirstName {get;}
string MiddleName {get;}
string LastName {get;}
string Quest {get;}
string FavoriteColor {get;}
}
public static List<PersonSearchResult> Run(PersonSearchCriteria criteria)
{
// create a query using the given criteria
// run the query
// return the results
}
}
public class PersonSearchTester
{
public void Test()
{
PersonSearch.PersonSearchCriteria criteria = new PersonSearch.PersonSearchCriteria();
criteria.FirstName = "George";
criteria.LastName = "Washington";
List<PersonSearch.PersonSearchResults> results =
PersonSearch.Run(criteria);
}
}

Categories