We're working with XML and want a common interface amongst the main XML class and all of its components. However, sub-components of the XML class need additional methods, but they also need the main component's methods. Seems like a great use for inheritance.
Here is some code I wrote to accomplish this task. Hopefully, you can get a good idea of what we're going for based on usage:
using System;
namespace SampleNamespace
{
public class SampleClass
{
public static void Main()
{
var xmlDocumentFiles = new XmlDocumentFiles();
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
System.Console.WriteLine(
xmlDocumentFiles.Files.RootFile.GetFileName()
);
}
}
public class XmlDocumentFilesRoot
{
protected string _rootFileName;
public FilesClass Files { get { return (FilesClass) this; } }
}
public class FilesClass : XmlDocumentFilesRoot
{
public RootFileClass RootFile { get { return (RootFileClass) this; } }
}
public class RootFileClass : FilesClass
{
public void SetFileName( string newTitle )
{
_rootFileName = newTitle;
}
public string GetFileName()
{
return _rootFileName;
}
}
public class XmlDocumentFiles : RootFileClass
{
}
}
I was able to cast to child classes and to my surprise it runs just fine. Assuming nothing is put inside of the sub-classes other than methods which wouldn't make sense in the parent, will there ever be any problems (weird compilation errors, runtime crashes) with this class structure?
Are there any alternatives? I had initially tried nested classes + extension methods located outside of the main class, but there was a lot of code needed to set that up. See: https://stackoverflow.com/questions/19415717/using-c-sharp-extension-methods-on-not-in-nested-classes-to-establish-a-common
Extending functionality of a class, sounds like a decorator pattern.
Here's a head-first pdf on this subject:
http://oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf
Also; I would like to discourage the triple '.' :
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
2 is evil, if you need 3: you will definitely lose maintainability.
Hope it helps.
Related
Apologies but this is new to me, I will gladly explain further or edit this post where necessary.
I have a project class library which I need to create a wrapper class library for. This class contains custom classes for constructors, which are then used as parameters in the methods that I'll be calling from my wrapper.
Within my wrapper I don't really want to have to use a using statement referencing the original class library, so I was wondering what the best way to handle these custom constructors are?
Here is an example I knocked up of what the DLL I'm wrapping looks like:
public CustomResult WriteMyDataAndReturnResult(CustomerWriterData data)
{
CustomerResult result = // Do stuff
return result;
}
public partial class CustomResult
{
private int resultId;
private MyResponse response;
public int resultIdField
{
get { return this.resultId; }
set { this.resultId = value; }
}
}
public partial class MyResponse
{
private string myMessage;
public string myMessageField
{
get { return this.myMessage; }
set { this.myMessage = value; }
}
}
public partial class CustomerWriterData
{
private string outputPath;
private string inputPath;
public string myOutputPath
{
get { return this.outputPath; }
set { this.outputPath = value; }
}
public string myInputPath
{
get { return this.inputPath; }
set { this.inputPath = value; }
}
}
So in the example above in my wrapper I'd be looking to have a method that calls WriteMyDataAndReturnResult, but this contains a custom object. What would be the best way to handle things in terms of this? I have toyed with the idea of recreating each of the partial classes in my wrapper, and then having convert methods to change from one to the other, but this seems like I'd be re-writting a lot of code.
Is there a better way for me to avoid having to include a using statement to the original library within code that calls my wrapper project?
Sorted it myself by creating a script that mapped the API to my DTO objects. This wasn't the path I specifically wanted to take, but it at least allowed me to create a separation between the 3rd party API and my main code.
I'm working on a game that uses MVCS and has, so far, clearly separated the business logic from the view.
However, I've been having trouble with one particular piece of the puzzle.
In the game we have command classes (IPlayerCommand) that execute a specific business logic. Each command class returns a result class (PlayerCommandResult). For each PlayerCommand we have a respected visual command class (IVisualPlayerCommand) that takes the PlayerCommandResult and updates the view accordingly.
I'd like the IVisualPlayerCommand to use specific classes that inherit PlayerCommandResult in order to get the information it needs (as opposed to using object). I'd also like to make it compile-time safe (as opposed to casting it before using it). For these two reasons I made the classes use generics.
Here are the declaration of the classes:
public class PlayerCommandResult
{}
public interface IPlayerCommand<T> where T : PlayerCommandResult
{
T Execute(GameWorld world);
}
public interface IVisualPlayerComamnd<T> where T : PlayerCommandResult
{
void Play(T commandResult);
}
Here is the Move Unit command as an example:
public class MoveUnitPlayerCommand : IPlayerCommand<MoveUnitPlayerCommandResult>
{
private Unit unitToMove;
public MoveUnitPlayerCommand(Unit unit)
{
this.unitToMove = unit;
}
public MoveUnitPlayerCommandResult Execute(GameWorld world)
{
MoveUnitPlayerCommand result = new MoveUnitPlayerCommand();
// Do some changes to the world and store any information needed to the result
return result;
}
}
public class MoveUnitVisualPlayerCommand : IVisualPlayerCommand<MoveUnitPlayerCommandResult>
{
void Play(MoveUnitPlayerCommandResult commandResult)
{
// Do something visual
}
}
public class MoveUnitPlayerCommandResult : PlayerCommandResult
{
public Unit TargetUnit { get; private set; }
public Path MovePath { get; private set; }
}
So far, so good. However, I'm having a really hard time tying a IPlayerCommand to a IVisualPlayerCommand because of the use of generics:
public class CommandExecutorService
{
public void ExecuteCommand<T>(IPlayerCommand<T> command) where T : PlayerCommandResult
{
T result = command.Execute(world);
IVisualPlayerCommand<T> visualCommand = GetVisualPlayerCommand(command);
visualCommand.Play(result);
}
public IVisualPlayerCommand<T> GetVisualPlayerCommand<T>(IPlayerCommand<T> command) where T : PlayerCommandResult
{
// ?!?!?!?!?!??!?!?!??!?!
}
}
I have a feeling that what I'm trying to do is not even possible because of the way generics work in C# (as opposed to Java where I could say IVisualPlayerCommand<?>).
Could you help me figure out a way?
Any feedback for the design is welcome.
P.S. Sorry if the title doesn't reflect the question. I wasn't sure how to boil down the question in one line.
P.P.S. Which is why I also don't know if this question has been asked and answered before.
You two command classes, are served as service. To me, for this case, I would use the service locator pattern. As how to implement this pattern, you can check this link
The drawback of using template, is that, if something changes, you have to compiled it again.
Here's link which provides an example of the service locator pattern.
So for you code, you want find the corresponding instance of IVisualPlayerCommand to IPlayerCommand, so the concrete service can inherit from both interface, which it actually implements the IVisualPlayerCommand interface, while the IPlayerCommand just severs as a tag.
so the code will like this:
class MoveUnitVisualPlayerCommand: IVisualPlayerCommand, IPlayerCommand {}
services = new Dictionary<object, object>();
this.services.Add(typeof(IPlayerCommand ), new MoveUnitVisualPlayerCommand());
as how to get the service, you can refer the example.
Hope this helps.
I have two classes that I'd like to keep in separate files.
namespace GridSystem
{
public class Grid
{
public void AddItem(GridItem item)
{
item.InformAddedToGrid();
}
}
}
namespace GridSystem
{
public class GridItem
{
public void InformAddedToGrid()
{
Debug.Log("I've been added to the grid");
}
}
}
How do I ensure no other classes are allowed to call InformAddedToGrid?
I'm trying to emulate Actionscript namespaces, which can be used on a method, in place of public, private, internal, etc. It doesn't exactly protect the method, but forces an extra step of including the namespace before the method can be accessed. Is there an alternative approach to this in C#?
If GridItem itself can be hidden from the outside world as well I would consider putting GridItem inside Grid as a nested class. That way it won't be visible outside of the class
http://www.codeproject.com/Articles/20628/A-Tutorial-on-Nested-Classes-in-C
Not that you should do this, you should do what TGH suggests, have a public interface for GridItem, and have gridItem nested in Grid (then have a factory method on Grid to create Items and use partial Grid class to have them in separate files).
Because there isn't a way of having friend methods ( you can do friend classes through InternalsVisibleToAttribute )
You COULD do this ( but don't... )
public partial class Grid
{
public void AddItem(GridItem item)
{
item.InformAddedToGrid();
}
}
public class GridItem
{
public void InformAddedToGrid()
{
if (new StackTrace().GetFrame(1).GetMethod().DeclaringType !=
typeof(Grid)) throw new Exception("Tantrum!");
Console.WriteLine("Grid called in...");
}
}
then
var g = new Grid();
g.AddItem(new GridItem()); // works
new GridItem().InformAddedToGrid(); // throws a tantrum...
A really ugly answer would be to make it private and use reflection.
Another ugly answer would be to make it throw an exception if the caller is wrong.
Both of these are much slower to execute than a normal call also.
I don't think there's a good answer. C# doesn't have friends.
IMHO the answer is simple: access modifiers are just there to remind the programmer of the intent of how public/private a class should be. Through reflection you can lift those barriers.
The usage you make of a class is all in your hands: if your class is meant to only be used in one place, make it so. If anything, if a class has a special way of being used, document it - put it in the XML comments.
That said, in this specific example I'd believe since the GridItem doesn't add itself to the grid, it's not its job to notify about it (what if "I've not been added to the grid"?). I think InformAddedToGrid belongs somewhere in your Grid class as a private method, where there's a concept of adding an item... assuming that's what AddItem(GridItem) really does.
You can do it as TGH suggested, with nested classes, except the other way around. Nest Grid within GridItem and make InformAddedToGrid private. Here I use a nested base class so the public API can remain the same. Note that no one outside of your assembly can inherit from GridBase because the constructor is internal.
public class GridItem
{
public class GridBase
{
internal GridBase() { }
public void AddItem(GridItem item)
{
item.InformAddedToGrid();
}
}
private void InformAddedToGrid()
{
Debug.Log("I've been added to the grid");
}
}
public class Grid : GridItem.GridBase { }
Another option is to have GridItem explicitly implement an internal interface. This way no one outside of your assembly can use the interface by name and therefore cannot call InformAddedToGrid.
public class Grid
{
public void AddItem(GridItem item)
{
((IGridInformer)item).InformAddedToGrid();
}
}
public class GridItem : IGridInformer
{
void IGridInformer.InformAddedToGrid()
{
Debug.Log("I've been added to the grid");
}
}
internal interface IGridInformer
{
void InformAddedToGrid();
}
C#. I have a base class called FileProcessor:
class FileProcessor {
public Path {get {return m_sPath;}}
public FileProcessor(string path)
{
m_sPath = path;
}
public virtual Process() {}
protected string m_sath;
}
Now I'd like to create to other classes ExcelProcessor & PDFProcessor:
class Excelprocessor: FileProcessor
{
public void ProcessFile()
{
//do different stuff from PDFProcessor
}
}
Same for PDFProcessor, a file is Excel if Path ends with ".xlsx" and pdf if it ends with ".pdf". I could have a ProcessingManager class:
class ProcessingManager
{
public void AddProcessJob(string path)
{
m_list.Add(Path;)
}
public ProcessingManager()
{
m_list = new BlockingQueue();
m_thread = new Thread(ThreadFunc);
m_thread.Start(this);
}
public static void ThreadFunc(var param) //this is a thread func
{
ProcessingManager _this = (ProcessingManager )var;
while(some_condition) {
string fPath= _this.m_list.Dequeue();
if(fPath.EndsWith(".pdf")) {
new PDFProcessor().Process();
}
if(fPath.EndsWith(".xlsx")) {
new ExcelProcessor().Process();
}
}
}
protected BlockingQueue m_list;
protected Thread m_thread;
}
I am trying to make this as modular as possible, let's suppose for example that I would like to add a ".doc" processing, I'd have to do a check inside the manager and implement another DOCProcessor.
How could I do this without the modification of ProcessingManager? and I really don't know if my manager is ok enough, please tell me all your suggestions on this.
I'm not really aware of your problem but I'll try to give it a shot.
You could be using the Factory pattern.
class FileProcessorFactory {
public FileProcessor getFileProcessor(string extension){
switch (extension){
case ".pdf":
return new PdfFileProcessor();
case ".xls":
return new ExcelFileProcessor();
}
}
}
class IFileProcessor{
public Object processFile(Stream inputFile);
}
class PdfFileProcessor : IFileProcessor {
public Object processFile(Stream inputFile){
// do things with your inputFile
}
}
class ExcelFileProcessor : IFileProcessor {
public Object processFile(Stream inputFile){
// do things with your inputFile
}
}
This should make sure you are using the FileProcessorFactory to get the correct processor, and the IFileProcessor will make sure you're not implementing different things for each processor.
and implement another DOCProcessor
Just add a new case to the FileProcessorFactory, and a new class which implements the interface IFileProcessor called DocFileProcessor.
You could decorate your processors with custom attributes like this:
[FileProcessorExtension(".doc")]
public class DocProcessor()
{
}
Then your processing manager could find the processor whose FileProcessorExtension property matches your extension, and instantiate it reflexively.
I agree with Highmastdon, his factory is a good solution. The core idea is not to have any FileProcessor implementation reference in your ProcessingManager anymore, only a reference to IFileProcessor interface, thus ProcessingManager does not know which type of file it deals with, it just knows it is an IFileProcessor which implements processFile(Stream inputFile).
In the long run, you'll just have to write new FileProcessor implementations, and voila. ProcessingManager does not change over time.
Use one more method called CanHandle for example:
abstract class FileProcessor
{
public FileProcessor()
{
}
public abstract Process(string path);
public abstract bool CanHandle(string path);
}
With excel file, you can implement CanHandle as below:
class Excelprocessor: FileProcessor
{
public override void Process(string path)
{
}
public override bool CanHandle(string path)
{
return path.EndsWith(".xlsx");
}
}
In ProcessingManager, you need a list of processor which you can add in runtime by method RegisterProcessor:
class ProcessingManager
{
private List<FileProcessor> _processors;
public void RegisterProcessor(FileProcessor processor)
{
_processors.Add(processor)
}
....
So LINQ can be used in here to find appropriate processor:
while(some_condition)
{
string fPath= _this.m_list.Dequeue();
var proccessor = _processors.SingleOrDefault(p => p.CanHandle(fPath));
if (proccessor != null)
proccessor.Process(proccessor);
}
If you want to add more processor, just define and add it into ProcessingManager by using
RegisterProcessor method. You also don't change any code from other classes even FileProcessorFactory like #Highmastdon's answer.
You could use the Factory pattern (a good choice)
In Factory pattern there is the possibility not to change the existing code (Follow SOLID Principle).
In future if a new Doc file support is to be added, you could use the concept of Dictionaries. (instead of modifying the switch statement)
//Some Abstract Code to get you started (Its 2 am... not a good time to give a working code)
1. Define a new dictionary with {FileType, IFileProcessor)
2. Add to the dictionary the available classes.
3. Tomorrow if you come across a new requirement simply do this.
Dictionary.Add(FileType.Docx, new DocFileProcessor());
4. Tryparse an enum for a userinput value.
5. Get the enum instance and then get that object that does your work!
Otherwise an option: It is better to go with MEF (Managed Extensibility Framework!)
That way, you dynamically discover the classes.
For example if the support for .doc needs to be implemented you could use something like below:
Export[typeof(IFileProcessor)]
class DocFileProcessor : IFileProcessor
{
DocFileProcessor(FileType type);
/// Implement the functionality if Document type is .docx in processFile() here
}
Advantages of this method:
Your DocFileProcessor class is identified automatically since it implements IFileProcessor
Application is always Extensible. (You do an importOnce of all parts, get the matching parts and Execute.. Its that simple!)
I've got quite a number of classes, which have got the standard set and get methods. My problem is that many of these set methods should not be callable from outside the class which holds the objects. I'm not quite sure if there are any patterns or C# for lack of a better word - operations that would make this easier.
In reference to the code below, there are a number of classes similar to SecureSite, which the controller should be able to call functions or access variables to modify the SecureSite (and the other similar classes). However when the user asks to see SecureSite etc. they shouldn't be able to change this.
From my limited knowledge and the answers I've seen to similar questions on this site, the main issue appears to be that the Write_SecureSite can't be made fully immutable due to the List<String> AccessHistory variable. So, what I've come up with looks as ugly as a bulldogs backside and is just as messy. Essentially there is a Write version of the SecureSite class which contains a class within it, which returns a readonly version of the SecureSite class.
So, am I missing something magic in C# that would make this all so much easier?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReadOnlyExample {
public class Write_SecureSite {
private List<String> mAccessHistory;
public List<String> AccessHistory {
get {
return mAccessHistory;
}
}
public SecureSite ReadOnly {
get {
return new SecureSite(this);
}
}
public class SecureSite {
public SecureSite(Write_SecureSite aParent) {
AccessHistory=aParent.AccessHistory;
}
public IEnumerable<String> AccessHistory;
}
}
public static class Controller {
private static Write_SecureSite SimpleSecureSite=new Write_SecureSite();
public static Write_SecureSite.SecureSite Login(String MyLogin) {
SimpleSecureSite.AccessHistory.Add(MyLogin);
return SimpleSecureSite.ReadOnly;
}
public static Write_SecureSite.SecureSite Details() {
return SimpleSecureSite.ReadOnly;
}
}
public static class User {
public static void Miscellaneous() {
Controller.Login("Me");
Write_SecureSite.SecureSite SecureSite=Controller.Details();
//Not going to happen.
SecureSite.AccessHistory.Add("Me2");
//No problem.
foreach(String AccessedBy in SecureSite.AccessHistory) {
Console.Out.WriteLine("Accessed By: "+AccessedBy);
}
}
}
}
I suggest to use interfaces:
public interface IReadSecureSite
{
IEnumerable<String> AccessHistory { get; }
}
class Write_SecureSite : IReadSecureSite
{
public IList<String> AccessHistoryList { get; private set; }
public Write_SecureSite()
{
AccessHistoryList = new List<string>();
}
public IEnumerable<String> AccessHistory {
get {
return AccessHistoryList;
}
}
}
public class Controller
{
private Write_SecureSite sec= new Write_SecureSite();
public IReadSecureSite Login(string user)
{
return sec;
}
}
...
Controller ctrl = new Controller();
IReadSecureSite read = ctrl.Login("me");
foreach(string user in read.AccessHistory)
{
}
This is not so much an answer as a direction to look into. I am also struggling with the Immutable class
So far I am using my constructors to set my read-only private vars
I am using methods to update my lists internally instead of exposing them as public properties: ie. use public Void Add(string itemToAdd)
I am reading a book by Petricek and Skeet called "Real World Functional Programming" and it is helping me move in the direction you are discussing
Here is a small tutorial from the same author's that introduces some basic concepts: http://msdn.microsoft.com/en-us/library/hh297108.aspx
Hope this helps a bit
Update: I probably should have been clearer: I was looking to point you in the direction of a more functional view as opposed to rewriting the class you had listed in your question - my apologies (removed sample)