I don't understand the difference between these cases of "composition" in c#, could anyone explain?
class B
{
}
example 1:
class A : IDisposable
{
private B objB;
public A(){objB = new B();}
public void Dispose(){}
}
example 2:
class A : IDisposable
{
private B objB;
public A(B obj){this.objB = obj;}
public void Dispose(){}
}
example 3:
class A : IDisposable
{
private B objB;
public A(){}
public void Sample(){objB = new B();}
public void Dispose(){}
}
I know that one is not the composition, but I don't understand why.
Also, is there a difference in cases:
class B : IDisposable
{
//is there a difference if I will and won't implement the methods of the interface?
}
class A : IDisposable
{
public B objB {get;set;}
public A(){}
public void Sample(){}
public void Dispose(){}
}
So my questions about composition: 1) Is there a difference if the B in A is private or public? 2) Do I have to initialize the B in A to count it as a composition? If so, is there any difference in what way I will do this? 3) Can I use composition if both my classes implement the same interface, but one of them doesn't implement its methods? (the last example).
Thanks for the answers!
All are examples of composition, at least in the sense of composition vs inheritance. A useful memonic is that composition has a and inheritance is a. I.e. A has a B. On the other hand A is a IDisposable.
There is also composition vs aggregation. In this sense composition owns a while aggregation uses a. Example 1 and 3 are clear examples of ownership. For example 2 it is unclear, in some cases a constructor parameter might imply taking ownership of the object, in other cases it might not, and in some cases there is a separate parameter to decide if ownership should be transferred or not. In any case, "Ownership" usually only matters if the the object is IDisposable, so in this trivial example it is not really useful to talk aggregation vs composition.
The examples rather show different way to take dependencies, if the object B is required for the correct functioning of the object A, then A depends on B.
Example 1 is simply creating its dependency, and is typical when depending on 'simple' objects, like a list.
Example 2 can be called dependency injection, and is usually a good idea for more complex object hierarchies.
Example 3 could be called Initialization. I.e. your Sample-method is initializing the object, and must be called before the object can be used. I would try to avoid this, since it is easy to forget to call the initialization method. It is typically easier
Your last example would be of an optional property. I.e. A should work just fine if objB is not set by anyone, but may change its behavior if it is set.
To me this is a rater poor question. I do not think I have ever discussed composition vs aggregation, and composition vs inheritance is usually mentioned to advocate against inheritance. I suspect the real point is regarding lifetimes and disposal. Any disposable object needs to be disposed, and it should always be clear who is responsible for disposing the object. A somewhat common pattern is something like this:
public class MyClass : IDisposable{
public MyDependency dep;
public suppressDispose;
public MyClass(MyDependency dep, bool suppressDispose = false) => (dep, suppressDispose ) = (dep, suppressDispose );
public void Dispose(){
if(!suppressDispose) dep.Dispose();
}
}
That takes over ownership by default, but allow for an opt out if the dependency need to be used later.
Related
So I have a class A. It defines a lot of the behaviour (methods), but also leaves a lot to the subclasses to implement. This class is never going to have an instance. This is just going to define the behaviour that is common to all subclasses.
The subclasses (A1, A2, A3, etc.) that are going to extend A are all going to be singletons. I don't want these subclasses to have multiple instances.
So the obvious way to do this would be create an abstract class A and then static classes A1, A2, A3 that extend A.
But apparently, this isn't allowed in C#. I'm assuming there is a good reason for this. People at Microsoft probably know a lot more about objected-oriented software design than I do.
But I just need some help in figuring out why this design is "poor" and what would be an alternate better design.
I'm writing a RESTful API using WCF. There is a bunch of database tables that this service is going to perform CRUD operations on. There is a lot of code that is going to be common to all tables and a lot of code that is going to be specific to each table. Also, only one operation can be performed on the table at any given time.
So I thought I could have an abstract class TableHandler. And then multiple extensions of it such as TableAHandler, TableBHandler etc. Since I only want one instance of these subclasses, I wanted to make them static.
Inheritance is something that affects objects. By definition, static classes do not allow instantiation. Therefore, they can't be involved in inheritance.
More practically, static methods can't be virtual, which pretty much eliminates any possible usefulness of being able to declare inherited static classes.
Create a normal class that extends your base but follow the singleton pattern with a private constructor and static accessor to the instance.
abstract class A { }
class A1 : A
{
private static A1 instance;
public static A1 Instance
{
get
{
if( instance == null )
instance = new A1();
return instance;
}
}
private A1() { }
}
As noted by #ScottChamberlain, this implementation is not thread-safe. Using a static constructor will make the initialization thread-safe. More information can be found in this question: Is the C# static constructor thread safe?
Simplest way to define singleton pattern is Lazy<T>:
public abstract class A { }
public class B : A
{
private static Lazy<B> _instance = new Lazy<B>(() => new B());
private B() { }
public static B Instance
{
get
{
return _instance.Value;
}
}
}
This will also provide thread-safety to creation of your singleton.
I asked this question yesterday, but I think it was unclear what my primary concern was. In C++, we have private and multiple inheritance, which enables us to add private methods to classes by just inheriting from the class declaring these methods. That is, if there's a class
class B {
public:
virtual void doMethodB();
};
and a class
class A : private B {
virtual int doMethodA();
};
doMethodB() can be called from within doMethodA(), but is not accessible from outside.
Now, I'd like to mimic this behavior in C#. There is no multiple nor private inheritance. Up to know, I can think of four way to achieve somthing similar, but still with serious drawbacks:
First: Use an interface, i.e.
interface IB {
public void doMethodB();
};
class A : IB {
public void doMethodB();
int doMethodA();
};
However, when we do this, doMethodB() is public, and must be implemented in each class inheriting from IB.
Second: Use a static method
public static class B {
public static void doMethodB();
};
That way, there need only be one implementation, but the method is still public and can't be restricted to certain classes.
Third: Use a extension method, like that. That way however, the method is called on the object (i.e. a.doMethodB()) and not from "inside".
Fourth: Composition.
class A {
private B b;
public int doMethodA();
};
Now, B's methods can be called like b.doMethodB() from A only, but are other issues now regarding serialization, b == null etc.
Is there another alternative? And if not, which one among the presented ones would you consider "the best"?
Regarding your "First" proposal with interfaces: you can also implement the interface explicitly:
"A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. "
See / Source: http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx
However, i would choose the Composition approach. "Favor Composition over Inheritance", also see Prefer composition over inheritance?
Ideally, i would constructor-inject B into A by dependency injection, that should help mitigate your b == null concern.
Note:
Using a static method / extension method (is a static method, too...) makes unit-testing A (respectively faking B) very hard, which is why i would forgo these solutions completely.
Edit:
If you don't need B.doMethodB accessible from anyone else than A, you can also make B an abstract class and B.doMethodB a protected method.
But i was thinking that you already know that ;-)
(And because of the testing issues i would still favor composition over inheritance).
I think the concept you are looking for is the protected access modifier. It means that only B itself and its derived classes can access the method, but others cannot.
class B {
protected virtual void DoMethodB() {}
}
class A : B {
virtual void DoMethodA() {
DoMethodB();
}
}
If you wanted, you can further restrict the access to protected internal which means that the method can only be accessed from derived classes inside your assembly.
Also, be aware of the consequences of virtual methods. If there is no explicit need to make a method virtual, it should not be marked virtual.
I have a question about coding practice. I want to create a class which can't be initialized. I believe I have 3 options:
Abstract modifier
Static modifier
Private constructor
I don't want to create a static class simply because of having to name all of my properties and methods 'static' - it looks messy (and I can't use the 'this' keyword).
According to the MSDN:
Use the abstract modifier in a class declaration to indicate that a
class is intended only to be a base class of other classes.
Edit Nothing will inherit form this class.
However, it would be a solution (but it seems wrong to me to use it in this situation).
Or, I can make a private constructor so the class cannot be initialized.
If it helps the reason for why is this: The class is responsible for starting off a work flow process. It doesn't need to be initialized since nothing is returned - it just needs to be 'started'.
Demo code
class Program
{
static void Main(string[] args)
{
WorkFlow wf = new WorkFlow(); // this will error which is fine!
ComplexObject co = new ComplexObject();
WorkFlow.Begin(co);
Console.ReadKey();
}
}
public class WorkFlow
{
private WorkFlow()
{
//private to prevent initialization but this feels wrong!
}
public static void Begin(ComplexObject co)
{
//code to begin the workflow
}
}
I want to create a class which can't be initialized.
That leaves the possible usages: static or base-class only.
If your class is going to be derived from, use abstract. A private/protected constructor would be a hack in this situation.
Your sample code looks more like a static class. With Singleton as alternative.
What about doing just what you have done but using your Begin method as a factory to create your workflow.
var workflow = Workflow.Begin(complexObject);
public class WorkFlow
{
private WorkFlow()
{
//private to prevent initialization but this feels wrong!
}
public static WorkFlow Begin(ComplexObject co)
{
return new Workflow(co);
}
}
Good practice: Private constructor (at least is what the GOF book recommends when using the Factory pattern, for example). I'll suggest you to use abstract if it's a base class (that's what it's name suggest).
If the class is strictly being used as a base class, it would have to be abstract for me.
Based on your update I would go for a static class & method e.g.
WorkFlow.Begin(co);
However, since you don't want to do this I think it only leaves you with one option...private constructor.
Seems like you would need a singleton.
More reference here:
http://msdn.microsoft.com/en-us/library/ff650849.aspx
if you dont like the ideea, well an abstract class would be best suited because as you said you dont want to instantiate it, and lets not forget that the abstract class does just that, so why try and use a private constructor.
I don't want to create a static class simply because of having to name
all of my properties and methods 'static' - it looks messy (and I
can't use the 'this' keyword).
Well, either you make ctor private or make a class static, the only way caller can access methods and properties of your class (if the caller is not derived one) is via public static members.
Having private ctor give you more flexibility in inheritance chain, but doesn't help much in "avoid static members" scenario.
I will prefer private constructor ie its identical to Singleton pattern
Info
Coding
Private constructors seems to be good approach for your requirement. Abstracts are good too but private constructor is handy than abstract. But if you would like to extend its information then its probably good idea to use abstract.
If the class needs to be "started" it needs to be initialized (unless all you're going to use are static methods).
Abstract classes are used to leave some (or all) of the implementation to subclasses, and by your description - not suitable for you.
"Static classes" - no special gain here I guess (in your case).
Private constructors - used to limit who can instantiate the class.
Not sure that any of these matches your design, but I guess you really want a singleton - look it up, this is the most common and basic design pattern.
BTW - I use singletons only as a last resort, usually when the class controls some kind of non shared resource.
I've got a couple of classes that form a too-complicated object graph. Here's a peek at a smaller scenario. Assume INotifyPropertyChanged is in place.
class A
{
public InternalType InterestingProperty { get; set; }
}
class B
{
public A Component { get; set; }
}
My helper class watches for these events and updates its properties when the properties of the objects change. It does this so some other class that's interested in about a dozen properties on as many objects are easily accessible. This is all packed in a framework that has several variants, so inheritance is in play.
I've finished the first scenario, and ended up with a concrete class like this:
class ScenarioOnePropertySpy
{
protected ScenarioOne PropertySpy(Foo thingToMonitor)
{
_thingToMonitor = thingToMonitor;
RegisterForEvents()
}
public B InterestingB { get; }
protected RegisterForEvents()
{
// * Register for _thingToMonitor propertyChanged if first time.
// * If B is different, unregister the old and register the new.
// * If B hasn't been set yet register for PropertyChanged on it.
// * If B.Component isn't the same as last time unregister the
// old and register the new.
}
protected Update()
{
// Some monitored object changed; refresh property values and
// update events in case some monitored object was replaced.
B = _thingToMonitor.B;
RegisterForEvents()
}
private Handle_PropertyChanged(...) { Update(); }
}
It's icky event registration, but moving that ugliness out of the class that wants to know about the properties is the purpose. Now I've moved on to scenario 2 that monitors different objects/properties and used my concrete class as a guide for an abstract one:
abstract class PropertySpy
{
protected PropertySpy(FooBase thingToMonitor)
{
_thingToMonitor = thingToMonitor;
RegisterForEvents()
}
protected abstract void RegisterForEvents()
// ...
}
Whoops. I've got a virtual method call in the constructor. In theory it's safe for all of my scenarios, but the R# warning keeps digging at me. I'm sure if I move forward one day it's going to cause a problem that'll take a while to figure out. That method's definitely going to need to work with properties on the derived types.
I could drop the method and force derived types to do the event management themselves. That'd defeat the purpose for the base class. And someone would forget to follow the contract and it'd turn into a support incident; I spend enough time writing documentation as it is. Another one I thought of was making RegisterForEvents() publich and requiring users to call it after construction. That "create then initialize" pattern stinks in .NET and people always forget. Currently I'm toying with the notion of another class that does the event registration that's injected via the constructor. Then derived classes can provide that class to achieve the same effect as a virtual method without the dangers. But the thing doing the registration would need practically the same property interface as PropertySpy; it seems tedious but I guess "ugly and works" is better than what I've got.
Anything I'm missing? I'll even take "it's a warning, not a rule" as an answer if the argument is convincing.
Your scenario seems complicated enough to consider a completely different approach to class instantiation. What about using a factory to construct property spies?
public class PropertySpyFactory<T> where T : PropertySpy, new()
{
public static T Create()
{
T result = new T();
// … whatever initialization needs to be done goes here …
result.RegisterForEvents();
return result;
}
}
ScenarioOnePropertySpy spy = PropertySpyFactory<ScenarioOnePropertySpy>.Create();
It's salvagable in the code, instance initialization can be extended easily, and once you turn to an IoC it will feel quite natural and not much refactoring will be needed.
UPDATE: One another option in case a) your spy hierarchy is flat enough and b) you don't need to use a common ancestor or you can substitute it with an interface:
public abstract class PropertySpy<T> where T : PropertySpy, new()
{
public static T Create()
{
T result = new T();
// … whatever initialization needs to be done goes here …
result.RegisterForEvents();
return result;
}
…
}
public class ScenarioOnePropertySpy : PropertySpy<ScenarioOnePropertySpy>
{
…
}
ScenarioOnePropertySpy spy = ScenarioOnePropertySpy.Create();
In other words, the factory method is located right within the common ancestor. The drawback of this approach is that it isn't that orthogonal (the factory isn't separated from the classes being constructed) and hence less extensible and flexible. However, in certain cases may be a valid option.
Last but not least, you can create a factory method in each class again. The advantage is you can keep constructors protected and hence force users to use factory methods instead of direct instantiation.
The key issue I believe is that by the time the virtual method is called, your subclass constructor and initializers have not executed yet. So, in your overridden method, your subclass may not have all the things you expect to be initialized initialized.
Let say I have a class like this:
public sealed class Foo
{
public void Bar
{
// Do Bar Stuff
}
}
And I want to extend it to add something beyond what an extension method could do....My only option is composition:
public class SuperFoo
{
private Foo _internalFoo;
public SuperFoo()
{
_internalFoo = new Foo();
}
public void Bar()
{
_internalFoo.Bar();
}
public void Baz()
{
// Do Baz Stuff
}
}
While this works, it is a lot of work...however I still run into a problem:
public void AcceptsAFoo(Foo a)
I can pass in a Foo here, but not a super Foo, because C# has no idea that SuperFoo truly does qualify in the Liskov Substitution sense...This means that my extended class via composition is of very limited use.
So, the only way to fix it is to hope that the original API designers left an interface laying around:
public interface IFoo
{
public Bar();
}
public sealed class Foo : IFoo
{
// etc
}
Now, I can implement IFoo on SuperFoo (Which since SuperFoo already implements Foo, is just a matter of changing the signature).
public class SuperFoo : IFoo
And in the perfect world, the methods that consume Foo would consume IFoo's:
public void AcceptsAFoo(IFoo a)
Now, C# understands the relationship between SuperFoo and Foo due to the common interface and all is well.
The big problem is that .NET seals lots of classes that would occasionally be nice to extend, and they don't usually implement a common interface, so API methods that take a Foo would not accept a SuperFoo and you can't add an overload.
So, for all the composition fans out there....How do you get around this limitation?
The only thing I can think of is to expose the internal Foo publicly, so that you can pass it on occasion, but that seems messy.
I found myself asking that same question until I started working on reusable libraries of my own. Many times you wind up with certain classes that just cannot be extended without requiring obscure or arcane sequences of calls from the implementor.
When allowing your class to be extended, you have to ask: if a developer extends my class, and passes this new class to my library, can I transparently work with this new class? Can I work properly with this new class? Is this new class really going to behave the same?
I've found that most of the time the sealed classes in the .Net Framework have certain under-the-hood requirements that you aren't aware of, and that given the current implementation cannot be safely exposed to subclasses.
This doesn't exactly answer your question, but it provides insight as to why not all classes are inheritable in the .Net Framework (and why you should probably entertain sealing some of your classes too).
I'm afraid the short answer is, you can't without doing what is required, i.e. pass the composed instance variable instead.
You could allow an implicit or explicit cast to that type (whose implementation simply passed the composed instance) but this would, IMO be pretty evil.
sixlettervariable's answer is good and I won't rehash it but if you indicated which classes you wished you could extend we might be able to tell you why they prevented it.