How to prevent inheritance for some methods? - c#

How can I prevent inheritance of some methods or properties in derived classes?!
public class BaseClass : Collection
{
//Some operations...
//Should not let derived classes inherit 'Add' method.
}
public class DerivedClass : BaseClass
{
public void DoSomething(int Item)
{
this.Add(Item); // Error: No such method should exist...
}
}

The pattern you want is composition ("Has-a"), not inheritance ("Is-a"). BaseClass should contain a collection, not inherit from collection. BaseClass can then selectively choose what methods or properties to expose on its interface. Most of those may just be passthroughs that call the equivalent methods on the internal collection.
Marking things private in the child classes won't work, because anyone with a base type variable (Collection x = new DerivedClass()) will still be able to access the "hidden" members through the base type.
If "Is-a" vs "Has-a" doesn't click for you, think of it in terms of parents vs friends. You can't choose your parents and can't remove them from your DNA, but you can choose who you associate with.

You can't, in this instance inheritance is the wrong tool for the job. Your class needs to have the collection as a private member, then you can expose as much or as little of it as you wish.

Trying to hide a public member of a class in a derived class is generally a bad thing(*). Trying to hide it as a means of ensuring it won't be called is even worse, and generally won't work anyhow.
There isn't any standardized idiomatic means I know of to prevent a parent class' protected member from being accessed in a sub-derived type, but declaring a new public useless member of a clearly-useless kind would be one approach. The simplest such thing would be an empty class. For example, if class Foo declares an empty public class called MemberwiseClone, derivatives of Foo will be unable to call MemberwiseClone--probably a good thing if MemberwiseClone would break the invariants of class Foo.
(*) The only situation where it is appropriate is when a public method of a derived class returns a more specialized type than the corresponding method in the base class (e.g. a CarFactory.Produce() method may return a Car, while the FordExplorerFactory.Produce() method may return a FordExplorer (which derives from car). Someone who calls Produce() on what they think is a CarFactory (but happens to be a FordExplorerFactory) will get a Car (which happens to be a FordExplorer), but someone who calls Produce() on what is known at compile time to be a FordExplorerFactory will get a result that's known at compile time to be a FordExplorer.

Related

C#: Force constructor signature using abstract class?

I've been searching for a while on this because I'm naturally forgetful and I thought it would be nice to build something (an abstract class, interface, etc.?) that would force me to implement certain bits of code in a class I was writing.
In particular, I would like to force a new class to always have a constructor that takes a single parameter typed as itself in order to make duplication of the object easier. I've seen articles/questions elsewhere that talk about this, but I'm not sure this particular question has been asked (at least that I can find) or I'm simply not understanding enough of the other articles/questions to realize it. My apologies in advance.
I'm not interested in having a constructor in an abstract class, interface, etc. actually do anything. I'm merely interested in defining the requirement for a constructor signature in a derived class.
My ideal class would look like this:
public class GoodClass
{
public GoodClass(GoodClass goodClass)
{
// copy components of goodClass to this instance
}
}
So, I first began researching interfaces and also started reading up on abstract classes. I was thinking something like the code below would work, but alas I get errors. Is what I'm trying to do even possible? Is there any other way I could accomplish my goal without putting a sticky note on my monitor? :)
abstract class SelfConstructor
{
abstract public SelfConstructor(SelfConstructor) { }
}
class NewClass : SelfConstructor
{
//Required by SelfConstructor:
public NewClass(NewClass newClass)
{
// copy components of newClass to this instance
}
}
You could write a ReSharper plugin that recognises this case and highlights the class if it doesn't have a "copy constructor". This would be a daemon stage that would process the file as it's being edited, and add highlights. You can look through the abstract syntax tree of the file, look for all instances of IConstructorDeclaration, and then get the constructor's parameters from the ParameterDeclarations property. You can check that there is a constructor that only has one parameter, and that parameter is the same type as the class it's declared in.
You can compare the types by getting the constructor's parameter's TypeUsage and trying to downcast to IUserTypeUsage. You can then use ScalarTypeName.Reference.Resolve() to get an instance of IDeclaredElement. Compare this against the class's IClassDeclaration.DeclaredElement to see if they're the same instance.
In C++, what you are talking about is a copy constructor, you actually get one by default!
C# doesn't have that concept (though of course you can define one); however, it is easier (and preferred) to simply implement ICloneable (MSDN), which requires you to implement the Clone method, that does the same thing.
Instead of:
object myObj = new CloneableObject(otherObj);
You write:
object myObj = otherObj.Clone();
The other thing you could do is force a constructor signature by not having a default:
public class BaseClass
{
//No abstract constructors!
public BaseClass(BaseClass copy)
{
}
}
Now when you derive, you have to use that overload in the constructor. Nothing will force the derived signature, but at least you have to explicitly use it:
public class DerivedClass : BaseClass
{
public DerivedClass() : base(this)
{
}
}
The above example clearly shows that it doesn't "force" you to have a copy constructor, but like a sticky note, would serve as a good reminder.
I would definitely go the interface route, as that is what is there for (and you can use an abstract implementation!).
Note that you can take advantage of Object.MemberwiseClone if you want a shallow copy for free. All objects get this, no interface required.

CA1033 with Properties

When I run code analysis (VS2013) with the 'Microsoft Managed Recommend Rules' rule set, the only warnings I get for my class library are of type CA1033: 'Interface methods should be callable by child types'. But I don't understand the rule in this situation:
/// An object that has a chemical formula
public interface IChemicalFormula
{
/// The chemical formula of the object
ChemicalFormula ChemicalFormula {get;}
}
public class ChemicalFormula: IChemicalFormula
{
ChemicalFormula IChemicalFormula.ChemicalFormula
{
get { return this; }
}
}
The docs recommends making a protected method with the same name so that deriving types can access it, but you cannot name a method the same as the enclosing type. They also recommend making the class sealed, but I don't want it to be sealed in this case. Is this a time just to ignore this rule, or is there an appropriate way to handle it?
EDIT
To add clarification why the class/interface is designed this way, I have another class, Peptide that contains a IChemicalFormula[] array to store modifications. Not every modification necessarily derives directly from ChemicalFormula, but they need to implement the IChemicalFormula interface. Therefore, if I modify an instance of a peptide withsome molecule (H2O for example), then ChemicalFormula class needs to also implement IChemicalFormula.
This is the description of the rule:
Consider a base type that explicitly implements a public interface
method. A type that derives from the base type can access the
inherited interface method only through a reference to the current
instance (this in C#) that is cast to the interface. If the derived
type re-implements (explicitly) the inherited interface method, the
base implementation can no longer be accessed. The call through the
current instance reference will invoke the derived implementation;
this causes recursion and an eventual stack overflow.
I think you should consider evaluating the usage of this property. A good example where TDD could be used to figure out the interface. There are some possible usages (and some invalid ones) below. I am not yet sure what you intend to achieve by looking at those.
In your example, let's say another class, NewChemicalForumla is derived from ChemicalForumula, and references ChemicalFormula, what does that mean?
public class NewChemicalFormula: ChemicalFormula
{
public void Method()
{
Console.WriteLine("{0}", ChemicalFormula.GetType()); // Compile error
Console.WriteLine("{0}", this.ChemicalFormula.GetType()); // Effectively same as above, compile error
Console.WriteLine("{0}", ((IChemicalFormula)this).ChemicalFormula.GetType()); // Works, is that what you intend?
}
}
Now from outside the class, there are two possibilities:
When you have a handle to a derived class:
new NewChemicalFormula().ChemicalFormula.GetType() // Error
or
// This works, is that what you intend to achieve?
((IChemicalFormula)new NewChemicalFormula()).ChemicalFormula.GetType()
When you have a handle to the IChemicalFormula already. In this case, ChemicalFormula seems redundant:
IChemicalFormula formula = new NewChemicalFormula();
Console.WriteLine("{0}", formula.GetType()); // Works, returns NewChemicalFormula
Console.WriteLine("{0}", formula.ChemicalFormula.GetType()); // Works, returns NewChemicalFormula
Console.WriteLine("{0}", formula.ChemicalFormula.Method()); // Compile error
formula.ChemicalFormula.Method() leads to an error because you must cast it to NewChemicalFormula before you can use Method(). Just because the property returns this doesn't help solve this problem.
So the FXCop warning is worth considering, and evaluating the design.

c# Factory Method and protection levels problem

I have a base class and several subclasses derived from that base class. I also have a static function in the base class that takes some parameters, and instantiates and returns an appropriate subclass based on input parameters ( my factory method.)
Now here's my problem: I want to ONLY allow instantiation of the subclasses FROM the factory method. But if I set the constructors of the subclasses to be protected, the base class can't see them. Is there an access modifier I'm missing that would allow the base class to call the subclasses constructors, but not not allow any other classes to call them?
Internal doesn't look like it will work either...I want to limit access to the subclass constructors to just the base class, there are other classes in the same assembly that should be able to access the base factory method and but not directly instantiate any of the subclasses.
Hopefully there's something really simple I'm missing...
Example:
public class Base
{
public Base CreateChild(string childType)
{
if(childType == "A")
return new ChildA();
if(childType == "B")
return new ChildB();
return null;
}
}
public class ChildA
{
protected ChildA() // This doesn't work, since now base class can't call this!
{
}
}
public class ChildB
{
protected ChildB()
{
}
}
You can declare the child classes as private nested classes inside Base
Have you tried declaring the child classes within the base class?
public class Base {
protected class ChildA {}
protected class ChildB {}
}
If accessing any derived object through the base type is a valid scenario (let's say derived types only override base implementations and do not add new functionality) then the proposed solution of making the derived types nested private classes (as previous answers propose) is the best solution.
If that's not the case then I think you are falling into a case of unjustified complexity. What is the reason why code from your same assembly can not access ChildA and ChildB constructors? It is after all code you can control, so you can always choose to make / enforce via code review that he initalization is through the factory method.
I understand there is valid reasons to not let external assemblies freely instantiate objects except through a tightly controlled mechanism. In this case just marking the constructors as internal would do.
Otherwise, I'm not sure you can achieve what you are pretending without creating a specific assembly just for this base class and its derived classes. There is definitely no access modifier that would make a static method in a derived class only visible from it's base class.

C# class design - what can I use instead of "static abstract"?

I want to do the following
public abstract class MyAbstractClass
{
public static abstract int MagicId
{
get;
}
public static void DoSomeMagic()
{
// Need to get the MagicId value defined in the concrete implementation
}
}
public class MyConcreteClass : MyAbstractClass
{
public static override int MagicId
{
get { return 123; }
}
}
However I can't because you can't have static abstract members.
I understand why I can't do this - any recommendations for a design that will achieve much the same result?
(For clarity - I am trying to provide a library with an abstract base class but the concrete versions MUST implement a few properties/methods themselves and yes, there are good reasons for keeping it static.)
You fundamentally can't make DoSomeMagic() work with the current design. A call to MyConcreteClass.DoSomeMagic in source code will be translated into MyAbstractClasss.DoSomeMagic in the IL. The fact that it was originally called using MyConcreteClass is lost.
You might consider having a parallel class hierarchy which has the same methods but virtual - then associate each instance of the original class with an instance of the class containing the previously-static members... and there should probably only be one instance of each of those.
Would the Singleton pattern work perhaps? A link to the MSDN article describing how to implement a singleton in C#:
http://msdn.microsoft.com/en-us/library/ff650316.aspx
In your particular example, the Singelton instance could extend an abstract base class with your MagicId in it.
Just a thought :)
I would question that there are "good reasons" for making the abstract members static.
If your thinking is that these members might reflect some property of the derived class itself rather than a given instance, this does not necessarily mean the members should be static.
Consider the IList.IsFixedSize property. This is really a property of the kind of IList, not any particular instance (i.e., any T[] is going to be fixed size; it will not vary from one T[] to another). But still it should be an instance member. Why? Because since multiple types may implement IList, it will vary from one IList to another.
Consider some code that takes any MyAbstractClass (from your example). If this code is designed properly, in most cases, it should not care which derived class it is actually dealing with. What matters is whatever MyAbstractClass exposes. If you make some abstract members static, basically the only way to access them would be like this:
int magicId;
if (concreteObject is MyConcreteClass) {
magicId = MyConcreteClass.MagicId;
} else if (concreteObject is MyOtherConcreteClass) {
magicId = MyOtherConcreteClass.MagicId;
}
Why such a mess? This is much better, right?
int magicId = concreteObject.MagicId;
But perhaps you have other good reasons that haven't occurred to me.
Your best option is to use an interface with MagicId only using a setter
public interface IMagic
{
int MagicId { get; }
}
By the nature of Static meaning there can only be one (yes like Highlander) you can't override them.
Using an interface assumes your client will implement the contract. If they want to have an instance for each or return the value of a Static variable it is up to them.
The good reason for keeping things static would also mean you do NOT need to have it overridden in the child class.
Not a huge fan of this option but...
You could declare the property static, not abstract, virtual and throw a NotImplementedException which returns an error message that the method has to be overridden in a derived class.
You move the error from compile time to run time though which is kinda ugly.
Languages that implement inheritance of static members do it through metaclasses (that is, classes are also objects, and these objects have a metaclass, and static inheritance exists through it). You can vaguely transpose that to the factory pattern: one class has the magic member and can create objects of the second class.
That, or use reflection. But you can't ensure at compile-time that a derived class implements statically a certain property.
Why not just make it a non-static member?
Sounds like a Monostate, perhaps? http://c2.com/cgi/wiki?MonostatePattern
The provider pattern, used by the ASP.NET membership provider, for example, might be what you're looking for.
You cannot have polymorphic behavior on static members, so you'll have a static class whose members delegate to an interface (or abstract class) field that will encapsulate the polymorphic behaviors.

Force calling the derived class implementation within a generic function in C#?

Ok so I'm currently working with a set of classes that I don't have control over in some pretty generic functions using these objects. Instead of writing literally tens of functions that essentially do the same thing for each class I decided to use a generic function instead.
Now the classes I'm dealing with are a little weird in that the derived classes share many of the same properties but the base class that they are derived from doesn't. One such property example is .Parent which exists on a huge number of derived classes but not on the base class and it is this property that I need to use.
For ease of understanding I've created a small example as follows:
class StandardBaseClass {} // These are simulating the SMO objects
class StandardDerivedClass : StandardBaseClass {
public object Parent { get; set; }
}
static class Extensions
{
public static object GetParent(this StandardDerivedClass sdc) {
return sdc.Parent;
}
public static object GetParent(this StandardBaseClass sbc)
{
throw new NotImplementedException("StandardBaseClass does not contain a property Parent");
}
// This is the Generic function I'm trying to write and need the Parent property.
public static void DoSomething<T>(T foo) where T : StandardBaseClass
{
object Parent = ((T)foo).GetParent();
}
}
In the above example calling DoSomething() will throw the NotImplemented Exception in the base class's implementation of GetParent(), even though I'm forcing the cast to T which is a StandardDerivedClass.
This is contrary to other casting behaviour where by downcasting will force the use of the base class's implementation.
I see this behaviour as a bug. Has anyone else out there encountered this?
I see this behaviour as a bug.
This behavior is correct. Since your method DoSomething is constraining T to StandardBaseClass, you only have access to the specific methods of StandardBaseClass, not any methods or properties of a derived class. Since StandardBaseClass does not have a Parent property, this is invalid, and should be invalid, by design.
There are two potential options here - You can use reflection to pull out the Parent property, or use C# 4's dynamic type, and treat this as a dynamic object. Both bypass the standard type checking in the compiler, however, so will require you to do extra type checking at runtime to verify that the Parent property exists.
Create an interface that contains the Parent property. Have each class that has a Parent property implement that interace. You will then be able to create a generic method that accepts a parameter of type IHaveParent, and it will do the right thing.
For anyone that is interested an succinct answer to this situation is answered by Stephen Cleary on msdn here:
http://social.msdn.microsoft.com/Forums/en-AU/csharpgeneral/thread/95833bb3-fbe1-4ec9-8b04-3e05165e20f8?prof=required
To me this is a divergence in the class hierarchy. By this this I mean that either the base class has parent, or the derived classes with Parent are derived from an abstract child of the base.
Lol as John says, an interface as opposed to an abstract class is sufficient too.
You idea won't work because the compiler can never guarantee that the base class actually would have such a property. And it won't just select the "right" one based on if it has it or not.
The only way you can do this is using reflection and then test at runtime if the requested property exists on the inspected class. You have to judge yourself if that is a viable way to do for your project (reflection is slow and requires maximum rights).
This is correct, as the compiler only knows that it can bind to your type as a StandardBaseClass. The binding is not done at runtime (where it could potentially decide to use the StandardDerivedClass overload.
If you know that it's a StandardDerivedClass, then why not just cast it as such?
object Parent = ((StandardDerivedClass)foo).Parent;
It's a bit ugly, but you can accomplish this using a Registration system, where you register delegates for different possible derived classes that expose the 'shared' property/method and then use something like a Dictionary<Type,Func<SomeT>> to store the delegates. If you know all of the derived types ahead of time and don't have to load plug-ins or the like, you can also use the classic ugly if/else-if structure. Either way you're basically creating your own substitute for what should have been supported by the virtual method table.

Categories

Resources