Hide Virtual function In Inherited Class - c#

I have a class that inherits from LinkButton and I want to hide OnClinentClick from my class.
Somthing like this :
public class MyClass : LinkButton
{
// some Code
}
And somewhere in code:
MyClass myclass = new MyClass();
MyClass.OnClinentClick = "";//this line must not be accessable

Hiding something from a class definition is not directly supported as it breaks OOP principles.
You could use the new operator, however, I wouldn't advise it. Personally, I would think about my design and/or use a NotSupportedException if there is no other way around it.

You can use the EditorBrowsableAttribute to prevent it from being suggested by IntelliSense, but you can't get rid of it entirely.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual string OnClientClick { get; set; }
C# only supports public inheritance. You shouldn't be inheriting from a class whose methods don't make sense for all derived classes. Consider composition instead of inheritance to solve this problem.

You can override the function (that is, replace the base implementation with your one, as long as the former is virtual), but you cannot completely prevent the clients from calling the base class function if you hide it with new, as they may always cast to the base class.
Update:
actually, you cannot change the access from public to protected/private when overriding, this won't compile (http://ideone.com/Y65Uh). Besides that, if you use new to hide the base function and make it uncallable, the original function is still visible (http://ideone.com/xiL2F). If you declare the new function public (which is perhaps not what you want), the old function can still be called by casting to the base class (http://ideone.com/A3Bji).

How about making giving it a lower visibility. One of protected and internal might be what you want. Of course that doesn't remove such a member from the derived class, but just removes them from the public interface. It also requires control over the base-class. No idea if LinkButton is one of your classes.
You could also hide the property by reintroducing a new one with the same. But that's a bad idea, and casting back to the base-class allows outsiders to access it.
And you should consider using a has-a relationship instead of an is-a. i.e. Don't derive from a base class if you don't want all its public members. This violates OOP principles such as that it should be possible to substitute the derived class where the base class is expected.
You could also override it, and make the setter throw a NotSupportedException. But that's ugly too because it will only show an error at runtime instead of compiletime. You can generate compile-time warnings with attributes such as the ObsoleteAttribute.

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.

Correct way to see if the current instance of a superclass is a subclass from within the superclass

Say I have a class called SuperClass and a class called SubClass. SubClass extends from SuperClass. Inside the definition of SuperClass I have a method that intends to check if this class is an instance of SubClass.
if (this.GetType() == typeof(SubClass))
log.Info("This SuperClass is a SubClass");
else
log.Info("This SuperClass is NOT a SubClass");
This works, but I'm always very skeptical when something works correctly (especially on the first try). I wanted to make sure this was the best way (safest, most readable, correct) to do what I want.
I think you're just looking for the is operator:
if (this is SubClass)
In particular, that will also continue if this is an instance of a subclass of SubClass.
If you then want to use this as SubClass, e.g. to get at a member declared in SubClass, you should consider the as operator too:
SubClass sub = this as SubClass;
if (sub != null)
{
// Use sub here
}
If you want to detect that this is an instance of exactly SubClass (and not further derived types) then the check you've got is already the right one.
One word of warning: the need to check for types at execution time is often a bit of a design smell. Think about whether there are alternative ways of achieving whatever your goal is. Sometimes there are (e.g. by introducing a new virtual or abstract member in the base class) and sometimes there aren't... but it's always worth thinking about.
This will work but you've coupled your super and sub classes where the super really shouldn't know about the sub. Create a virtual method on the super class that the sub will override to do the actual work. You can call this method from inside or outside of the super class to do the work you need. If the work needs to be done on members of the super class, then make them protected so the sub class can access them.
Let me add that almost anytime you need to check the type of an object, you aren't doing object oriented programming correctly and there is a better design to be found. Usually it's the sub class that needs to be doing the work that the type checking class is trying to do.

Can a class be aliased in C#?

In a namespace, is it possible to provide an alias for a class? And if not, why not?
By example, if I had several libraries of things that were derived from a contained, but named base class, but wanted to alias that as "BaseClass", while retaining its actual class name (i.e. "HtmlControl").
Then consumers could always come along and extend from HtmlControls.BaseClass, without having to figure out which class it really comes from.
using SomeClass = Large.Namespace.Other.FunkyClass;
class Foo : SomeClass
{
}
There really isn't an ideal way to do this in C#/.NET. What you can do is have a public BaseClass that inherits from an internal class. You can change this inheritance internally without breaking your consumers as long as the interface to the class remains intact.
public class PublicBaseClass : SomeInternalClass {
}
Consumers inherit from PublicBaseClass, and as long as you are careful, you can change what SomeInternalClass is as you wish.
You could create a dummy class that just inherits HtmlControl without adding any other functionality:
public class BaseClass : HtmlControl {}
The closest I know of is to customize your using statement:
using BaseClass = HtmlControls.BaseClass;
This is normally used to avoid ambiguity between classes with the same name in different used namespaces, without having to fully qualify one or the other. Your devs would have to include it in every code file, so probably not a good solution for what you're doing.
As far as deriving from BaseClass without knowing what you are actually deriving from, not possible. The compiler must, at some level, know what and where the parent class is, meaning it must be statically defined somewhere in code.

How to prevent inheritance for some methods?

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.

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