I have read several articles on when to use nested classes, but none that I've found address my specific question.
C# has a class called XmlReader which only provides a Create() method. I'm assuming that the create creates a subclass of XmlReader. If not, then for this example, assume that it does.
Consider this relationship:
/// <summary>
/// Class to read information in a file on disk
/// </summary>
interface ILoad
{
/// <summary> Version number of the file </summary>
int Version {get;}
/// <summary> Content of the file </summary>
string Content {get;}
/// <summary> Full path to the file </summary>
string FullPath {get;}
}
/// <summary> Provides base loading functionality </summary>
class LoaderBase : ILoad
{
public int Version {get; protected set;}
public string Content {get; protected set;}
public string FullPath{get; protected set;}
/* Helpers omitted */
protected abstract void Load(string pathToFile);
public static LoaderBase Create(string pathToFile)
{
switch(Path.GetExtension(pathToFile))
{
// Select the correct loader based on the file extension and return
}
return null;//unknown file type
}
}
/// <summary> Base class functionality to load compiled files </summary>
public abstract class CompiledLoaderBase : LoaderBase
{
protected CompiledLoaderBase(string path)
{
Load(path);
}
protected override Load(string path)
{
/* read the file and create an XmlReader from it */
ReadVersionNumber(reader);
ReadContent(reader);
}
protected abstract void ReadVersionNumber(XmlReader reader);
protected abstract void ReadContent(XmlReader reader);
// Wish I could call this Create, but inherited a static Create method already
public static CompiledLoaderBase CreateCompiled(string path)
{
//Figure out which loader to create and return it
// ... Assume we figured out we need V1
return new CompiledLoaderV1(path);
}
// Here's the fun stuff!
protected class CompiledLoaderV1 : CompiledLoaderBase
{
public CompiledLoaderV1(string path)
: base(path)
{}
protected override ReadVersionNumber(XmlReader reader)
{ /* read the version number and store in Version */ }
protected override ReadContent(XmlReader reader)
{ /* read the content and store in Content */ }
}
// ... More classes with their own methods for reading version and content
}
Now, I used nested classes to prevent the user from creating the specific loaders directly; they must use one of the abstract base's Create* methods. FxCop blew up in my face over this and I was hoping to get some clarification on why.
It mentioned not to use nested classes, but instead namespaces. Is there a way to accomplish this with namespaces?
EDIT: Specifically, the message is: "NestedTypesShouldNotBeVisible". Resolution: "Do not nest type 'CompiledLoaderBase+CompiledLoaderV1'. Alternatively, change its accessibility so that it is not externally visible." Info: "Do not use public, protected, or protected internal nested types as a way of grouping types. Use namespaces for this purpose. There are very limited scenarios where nested types are the best design." Now, I believe Jon Skeet identified that you cannot accomplish this with namespaces. I just wanted to make sure since this error says that there are a limited scenarios where this is the best design, so if there is a better one, I'm open to ideas :D
Also, it did not like virtual call chain called from constructor. Is there a reason for this? Is there a way around it?
EDIT: Specifically, the message is: "DoNotCallOverridableMethodsInConstructors". Resolution: "'CompiledLoaderV2.CompiledLoaderV2(String)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences"
Info: "Virtual methods defined on the class should not be called from constructors. If a derived class has overridden the method, the derived class version will be called (before the derived class constructor is called)". I feel like this could be a problem if the subclasses did something in their constructors, but since they do not, I'm not sure this is an issue. Is there a better way to force the classes to load in a certain way without using abstract methods in the constructor?
Thanks so much for all your help!
No, you can't do this with namespaces, although you can do it with assemblies - i.e. prevent anyone outside the assembly from creating an instance.
You can absolutely do it with nested classes, but you generally should make the constructor itself private to prevent anything else deriving from the class. You can also make the nested classes themselves private unless you need to them to the outside world.
You can use this pattern to create something like Java enums, and also limited factories. I've used it for a discriminated union in Noda Time - the actual details don't matter, but you might like to look at the source for more inspiration.
You're right to mistrust calling virtual methods from constructors. It can occasionally be useful but should be done very carefully with heavy documentation.
Consider making the classes internal. In this way they can then be instantiated within your assembly, but not by clients of your library. For testing purposes you can make a test assembly an explicit friend of your assembly so it can "see" internal types, and create instances of them - much better for testing.
Here's a rough idea. What if the constructor is public (allowing you to call it), but requires something the user can't get.
public interface ILoad
{
}
public abstract class LoaderBase : ILoad
{
public LoaderBase(InstanceChooser dongle)
{
if (dongle == null)
{
throw new Exception("Do not create a Loader without an InstanceChooser");
}
}
public abstract void Load(string path);
}
public class InstanceChooser
{
private InstanceChooser()
{
}
//construction and initialization
public static ILoad Create(string path)
{
InstanceChooser myChooser = new InstanceChooser();
LoaderBase myLoader = myChooser.Choose(path);
if (myLoader != null)
{
myLoader.Load(path); //virtual method call moved out of constructor.
}
return myLoader;
}
//construction
private LoaderBase Choose(string path)
{
switch (System.IO.Path.GetExtension(path))
{
case "z": //example constructor call
return new CompiledLoaderV1(this);
}
return null;
}
}
public class CompiledLoaderV1 : LoaderBase
{
public CompiledLoaderV1(InstanceChooser dongle)
: base(dongle)
{
}
public override void Load(string path)
{
throw new NotImplementedException();
}
}
PS, I hate returning null. Feels so much better to throw and not have to write a million null checks.
Edited: Here is an example:
class Program
{
static void Main(string[] args)
{
Shape shape = Shape.Create(args[0]);
}
}
public abstract class Shape
{
protected Shape(string filename) { ... }
public abstract float Volume { get; }
public static Shape Create(string filename)
{
string ext = Path.GetExtension(filename);
// read file here
switch (ext)
{
case ".box":
return new BoxShape(filename);
case ".sphere":
return new SphereShape(filename);
}
return null;
}
class BoxShape : Shape
{
public BoxShape(string filename)
: base(filename)
{
// Parse contents
}
public override float Volume { get { return ... } }
}
class SphereShape : Shape
{
float radius;
public SphereShape(string filename)
: base(filename)
{
// Parse contents
}
public override float Volume { get { return ... } }
}
}
it creates instances of Shape using nested classes for concrete classes, so that the user never bothers with the derived classes. The abstract class chooses the correct implementation and arguments based on the file extension and file contents.
Related
As CA2214 states, one should not call an overridable method in a constructor. However, I've come across a case where I can't see another way to do what I'm trying to achieve and I can't see potential problems arising from breaking this rule:
I have an abstract base class for configurations. In this class, there is logic for how to fetch the values.
My applications have configs that can be made up of certain components. So my SpecificConfig would inherit from ConfigBase and be made up of ConfigComponentA and ConfigComponentB:
public abstract class ConfigBase
{
protected ConfigBase()
{
this.InitializeMembers();
this.SetConfigValues();
}
protected abstract void InitializeMembers();
private void SetConfigValues() {
// Set the config values
// Depends on members initialized in InitializeMembers
}
}
public class ConfigComponentA
{
public string FieldA1;
public string FieldA2;
}
public class ConfigComponentB
{
public string FieldB1;
public string FieldB2;
}
public sealed class SpecificConfig : ConfigBase
public SpecificConfig() : base() {}
public ConfigComponentA ConfigA;
public ConfigComponentB ConfigB;
protected override void InitializeMembers()
{
this.ConfigA = new ConfigComponentA();
this.ConfigB = new ConfigComponentB();
}
}
The main point is that the configs could be made up of different components, and I want to avoid code duplication by having the logic for fetching and setting the config values in SetConfigValues() in the base class.
I have a feeling there may be a better way of going about this altogether, but I don't really see any unexpected behaviour that could come of this. Is there a better approach?
I have several classes with different properties and I want to do the same thing with instances of these classes. Lets say save their properties to text file with another informations (I don't have all the informations in that instance so I can't use something like ToString() method - I have to work with those properties in another class).
Here are example of two classes:
class Dog
{
public int Height { get; set; }
public string Name { get; set; }
}
class Car
{
public bool IsConvertible { get; set; }
public string VIN { get; set; }
}
In text file I want to have instances saved like:
20151023; Dog; 32 cm; My dog;
20151023; Car; true; WP0ZZZ99ZTS392124;
I thought that it would be nice to have special static class for every supported class with methods public static void Write(T) and public static T Read(string line). Both methods have same name in every class but slightly different functionality so I thought that Interface or Abstract class could work, but neither works with static methods.
Is there some way how I can be sure that those static methods are implemented in all classes?
Is it better to use "classic" classes instead of static ones in this case?
I am assuming that you are looking for an approach that allows you to define some abstraction that can be implemented for different classes. And that saving object content to some string is just an example of that. If this is not the case (i.e. you only care about serialization), then simply use the serialization API from the .NET framework.
Is there some way how I can be sure that those static methods are implemented in all classes?
You cannot do this with C# alone. You can use some tools that hook into the compilation process and allow you to set custom rules for your classes. I don't recommend you do this in this case though.
Is it better to use "classic" classes instead of static ones in this case?
Yes. I suggest that you create an generic interface.
I will use the same example (saving content or Serialization) that you provided:
public interface ISerializer<T>
{
string Read(T obj);
void Write(T obj, string data);
}
And then you can create serializers for the objects. Here is an example for the Dog object:
public class DogSerializer : ISerializer<Dog>
{
public void Write(Dog obj, string data)
{
//Parse the data string and set properties on the object
}
public string Read(Dog obj)
{
//Create a string by reading properties from the dog object
}
}
You can also create a generic serializer that uses Reflection to read/write properties from/to any object.
public class Serializer<T> : ISerializer<T>
{
public string Read(T obj)
{
//Use reflection here to read object properties
}
public void Write(T obj, string data)
{
//Use reflection here to set object properties
}
}
Is there a tool that can generate extract and generate interfaces for existing classes?
I know Visual Studio will extract an Interface for an existing class. However, I would also like to generate a wrapper class that implements that functionality.
I believe this would help tremendously for unit testing.
Example Existing Class:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
This can be generated by Visual Studio (Extract Interface):
public interface IThirdPartyClass
{
void Method1();
void Method2();
}
I would like to go one step further:
public class ThirdPartyClassWrapper : IThirdPartyClass
{
private tpc = new ThirdPartyClass();
public void Method1()
{
tpc.Method1();
}
public void Method2()
{
tpc.Method2();
}
}
Update:
This would be especially useful for static classes. As Morten points out I can just use a stub, however, I would like to break up my coupling if possible.
Found a way around it for non-sealed classes.
1 - Inherit from the external class
class MyWrapper : ExternalClass
2 - Extract interface for all public methods
class MyWrapper : ExternalClass, IExternalClass
3 - Remove the inheritance from the external class
class MyWrapper : IExternalClass
4 - You will get a hint on the class name about members from the interface not being implemented. Alt + Enter on it and let Resharper automatically implement them
5 - Use this code template to wrap properties
get { return $INNERCOMPONENT$.$NAME$; }
set { $INNERCOMPONENT$.$NAME$ = value; }
6 - Use this code template to wrap methods
return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
I don't know a tool that would do that for you.
You probably know, but Visual Studio goes just half step further - it can provide empty implementation of interface. I would stop there if it is one time task.
Depending on actual goal using some other way may work - i.e. for testing you can use mocking frameworks - usually there is a way to wrap existing class and override some methods as needed.
Another really slick way of doing this is to use Resharper to generate the "Delegating members" for you as described here: https://stackoverflow.com/a/2150827/1703887
Steps:
Create a new class that inherits from the class you want to wrap with a private variable of that class' type:
public class ThirdPartyClassWrapper : ThirdPartyClass
{
private ThirdPartyClass _ThirdPartyClass;
}
Do a Alt-Insert in/on the class to use Resharper to generate "Delegating members". Choose the methods you want to expose and pass through to the private variable.
If you have the free version of the GhostDoc extension installed you can highlight all of the created properties, methods, etc. and do a Ctrl-D to automatically grab all of the documentation from the base class and put it on the new members. (Resharper can do this too but I think you'd have to put "new" on each item which would then allow you to Alt-Enter and choose "Add xml-doc comments" from the Resharper popup menu).
You can then delete the base class and do some additional cleanup in case the method/property signatures expose any other types that you need to wrap.
What you are looking for is a stub, this can be done either by making your own stub implementation of the interface, or by using a mocking framework like Rhinomocks. Wrapping a difficult class in another class for testpurposes does nothing good for you.
Regards
Morten
I strongly suggest you look into a mocking framework like Fakeiteasy.
But to give you exactly what you asked for see below. I suspect ReSharper didn't have this operation when others answered.
add the interface to the class you wish to be the wrapping class
class MyWebElement : IWebElement { }
Find/Click "Delegate implementation of "YourInterfaceHere" to a new field
Select your options
Click finish and enjoy your new class
class MyWebElement : IWebElement
{
private IWebElement _webElementImplementation;
public IWebElement FindElement(By #by)
{
return _webElementImplementation.FindElement(#by);
}
public ReadOnlyCollection<IWebElement> FindElements(By #by)
{
return _webElementImplementation.FindElements(#by);
}
public void Clear()
{
_webElementImplementation.Clear();
}
public void SendKeys(string text)
{
_webElementImplementation.SendKeys(text);
}
public void Submit()
{
_webElementImplementation.Submit();
}
public void Click()
{
_webElementImplementation.Click();
}
public string GetAttribute(string attributeName)
{
return _webElementImplementation.GetAttribute(attributeName);
}
public string GetCssValue(string propertyName)
{
return _webElementImplementation.GetCssValue(propertyName);
}
public string TagName
{
get { return _webElementImplementation.TagName; }
}
public string Text
{
get { return _webElementImplementation.Text; }
}
public bool Enabled
{
get { return _webElementImplementation.Enabled; }
}
public bool Selected
{
get { return _webElementImplementation.Selected; }
}
public Point Location
{
get { return _webElementImplementation.Location; }
}
public Size Size
{
get { return _webElementImplementation.Size; }
}
public bool Displayed
{
get { return _webElementImplementation.Displayed; }
}
}
I have a design problem I'd like to solve.
I have an interface, lets call it IProtocol, which is implemented by two separate classes. We're looking at over 600 lines of code here. The vast majority of the stuff they do is the same, except for some specific areas, like DiffStuff();
Current structure is something like this:
public class Protocol1 : IProtocol
{
MyInterfaceMethod1()
{
Same1();
DiffStuff();
Same2();
}
}
And
public class Protocol2 : IProtocol
{
MyInterfaceMethod1()
{
Same1();
Same2();
}
}
I'm concerned with having copy-paste errors and the classic problem of code duplication if I keep the two protocols separate. We're talking about a full 600 lines of code each, not some simple methods.
I'm considering changing the implementation of Protocol1 to inherit from protocol2, like this (Protocol2 would mostly stay the same, except I'd have to wrap Same1() and Same2() into private methods.)
public class Protocol1 : Protocol2
{
void Same1()
{
base.Same1();
}
void Same2()
{
base.Same2();
}
MyInterfaceMethod1()
{
Same1();
DiffStuff();
Same2();
}
}
Is this the right way to go about dealing with this problem?
Edit:
Many people helped me with this question, thanks for the clear understanding. In my case, the two objects are not of the same type, even though much of their implementation is shared, so I went with Bobby's suggestion to use abstract base class, creating small methods to encapsulate changes between the classes. Additional Thanks to:
jloubert
Hans Passant
Jeff Sternal
/// <summary>
/// IProtocol interface
/// </summary>
public interface IProtocol
{
void MyInterfaceMethod1();
void Same1();
void Same2();
}
then...
public abstract class ProtocolBase : IProtocol
{
#region IProtocol Members
public void MyInterfaceMethod1()
{
// Implementation elided...
}
public void Same1()
{
// Implementation elided...
}
public void Same2()
{
// Implementation elided...
}
public abstract void DiffStuff();
#endregion
}
finally...
public sealed class Protocol1 : ProtocolBase
{
public override void DiffStuff()
{
// Implementation elided...
}
}
public sealed class Protocol2 : ProtocolBase
{
public override void DiffStuff()
{
// Implementation elided...
}
}
Not quite. There's no point in adding the Same1 and Same2 methods, you inherit them from ProtocolBase. And DiffStuff() should be a virtual method so that you can override it and give it different behavior.
You're awfully close to describing the template method pattern, which has a long pedigree as an effective solution to problems like yours.
However, you should consider using composition instead of inheritance. The two approaches offer different advantages and disadvantages, but composition is often (usually?) better *:
public class Protocol {
private ISpecialHandler specialHandler;
public Protocol() {}
public Protocol(ISpecialHandler specialHandler) {
this.specialHandler = specialHandler;
}
void Same1() {}
void Same2() {}
public void DoStuff() {
this.Same1();
if (this.specialHandler != null) {
this.specialHandler.DoStuff();
}
this.Same2();
}
}
Callers can then pass in object instances (strategies) that provide specialized algorithms to handle whatever case is at hand:
Protocol protocol1 = new Protocol(new DiffStuffHandler());
protocol1.DoStuff();
*See Patterns I Hate #2: Template Method for a detailed explanation of why composition is usually better than inheritance in your case.
You might want to consider whether this type of pattern works:
public class ProtocolHelper
{
public void Same1() {}
public void Same2() {}
}
public class Protocol1 : IProtocol
{
private readonly ProtocolHelper _helper = new ProtocolHelper();
void MyInterfaceMethod1()
{
_helper.Same1();
DiffStuff();
_helper.Same2();
}
}
You can tell if this makes sense by seeing if you can come up with a good name for the 'ProtocolHelper' class. If a name naturally arises from your logic, then this is a good way to break up the class. You might need to pass in some dependencies (such as private fields) as parameters to the methods in order to make this work.
I better design (in my opinion)
public abstract class Protocol_common : IProtocol
{
MyInterfaceMethod1()
{
Same1();
DiffStuff();
Same2();
}
abstract void DiffStuff();
}
public class Protocol1 : Protocol_common
{
DiffStuff()
{
/// stuff here.
}
}
public class Protocol2 : Protocol_common
{
DiffStuff()
{
/// nothing here.
}
}
(That's actually more pseudo-code than proper C#, but I hit the high points)
I agree with MathEpic. I would use Template method pattern.
Just the 5 minute overview would be nice....
public abstract class MyBaseController {
public void Authenticate() { var r = GetRepository(); }
public abstract void GetRepository();
}
public class ApplicationSpecificController {
public override void GetRepository() { /*get the specific repo here*/ }
}
This is just some dummy code that represents some real world code I have (for brevity this is just sample code)
I have 2 ASP MVC apps that do fairly similar things.
Security / Session logic (along with other things) happens the same in both.
I've abstracted the base functionality from both into a new library that they both inherit. When the base class needs things that can only be obtained from the actual implementation I implement these as abstract methods. So in my above example I need to pull user information from a DB to perform authentication in the base library. To get the correct DB for the application I have an abstract GetRepository method that returns the repository for the application. From here the base can call some method on the repo to get user information and continue on with validation, or whatever.
When a change needs to be made to authentication I now only need to update one lib instead of duplicating efforts in both. So in short if you want to implement some functionality but not all then an abstract class works great. If you want to implement no functionality use an interface.
Just look at the Template Method Pattern.
public abstract class Request
{
// each request has its own approval algorithm. Each has to implement this method
public abstract void Approve();
// refuse algorithm is common for all requests
public void Refuse() { }
// static helper
public static void CheckDelete(string status) { }
// common property. Used as a comment for any operation against a request
public string Description { get; set; }
// hard-coded dictionary of css classes for server-side markup decoration
public static IDictionary<string, string> CssStatusDictionary
}
public class RequestIn : Request
{
public override void Approve() { }
}
public class RequestOut : Request
{
public override void Approve() { }
}
Use of abstract method is very common when using the Template Method Pattern. You can use it to define the skeleton of an algorithm, and have subclasses modify or refine certain steps of the algorithm, without modifying its structure.
Take a look at a "real-world" example from doFactory's Template Method Pattern page.
The .NET Stream classes are a good example. The Stream class includes basic functionality that all streams implement and then specific streams provide specific implementations for the actual interaction with I/O.
The basic idea, is to have the abstract class to provide the skeleton and the basic functionality and just let the concrete implementation to provide the exact detail needed.
Suppose you have an interface with ... +20 methods, for instance, a List interface.
List {interface }
+ add( object: Object )
+ add( index:Int, object: Object )
+ contains( object: Object ): Bool
+ get( index : Int ): Object
+ size() : Int
....
If someone need to provide an implementation for that list, it must to implement the +20 methods every time.
An alternative would be to have an abstract class that implements most of the methods already and just let the developer to implement a few of them.
For instance
To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int index) and size() methods
AbstractList: List
+ get( index: Int ) : Object { abstract }
+ size() : Int { abstract }
... rest of the methods already implemented by abstract list
In this situation: get and size are abstract methods the developer needs to implement. The rest of the functionality may be already implemented.
EmptyList: AbstractList
{
public overrride Object Get( int index )
{
return this;
}
public override int Size()
{
return 0;
}
}
While this implementation may look absurd, it would be useful to initialize a variable:
List list = new EmptyList();
foreach( Object o: in list ) {
}
to avoid null pointers.
Used it for a home-made version of Tetris where each type Tetraminos was a child class of the tetramino class.
For instance, assume you have some classes that corresponds to rows in your database. You might want to have these classes to be considered to be equal when their ID is equal, because that's how the database works. So you could make the ID abstract because that would allow you to write code that uses the ID, but not implement it before you know about the ID in the concrete classes. This way, you avoid to implement the same equals method in all entity classes.
public abstract class AbstractEntity<TId>
{
public abstract TId Id { get; }
public override void Equals(object other)
{
if (ReferenceEquals(other,null))
return false;
if (other.GetType() != GetType() )
return false;
var otherEntity = (AbstractEntity<TId>)other;
return Id.Equals(otherEntity.Id);
}
}
I'm not a C# guy. Mind if I use Java? The principle is the same. I used this concept in a game. I calculate the armor value of different monsters very differently. I suppose I could have them keep track of various constants, but this is much easier conceptually.
abstract class Monster {
int armorValue();
}
public class Goblin extends Monster {
int armorValue() {
return this.level*10;
}
}
public class Golem extends Monster {
int armorValue() {
return this.level*this.level*20 + enraged ? 100 : 50;
}
}
You might use an abstract method (instead of an interface) any time you have a base class that actually contains some implementation code, but there's no reasonable default implementation for one or more of its methods:
public class ConnectionFactoryBase {
// This is an actual implementation that's shared by subclasses,
// which is why we don't want an interface
public string ConnectionString { get; set; }
// Subclasses will provide database-specific implementations,
// but there's nothing the base class can provide
public abstract IDbConnection GetConnection() {}
}
public class SqlConnectionFactory {
public override IDbConnection GetConnection() {
return new SqlConnection(this.ConnectionString);
}
}
An example
namespace My.Web.UI
{
public abstract class CustomControl : CompositeControl
{
// ...
public abstract void Initialize();
protected override void CreateChildControls()
{
base.CreateChildControls();
// Anything custom
this.Initialize();
}
}
}