Attributes in method override - c#

I have a base class with a method. Derived classes just need to decorate that method with an attribute (different for each derived class) and leave the body untouched.
I did something like
Base class
public virtual int Method1()
{
// body
}
public virtual int Method2()
{
// body
}
Derived class A
[AttributeA(ParameterName = "AName", CommandName = "ACommand")]
public override int Method1()
{
return base.Method1();
}
[AttributeA(ParameterName = "AnotherName", CommandName = "AnotherCommand")]
public override int Method2()
{
return base.Method2();
}
Derived class B
[AttributeB(ParameterName = "BName", CommandName = "BCommand")]
public override int Method1()
{
return base.Method1();
}
[AttributeB(ParameterName = "BnotherName", CommandName = "BnotherCommand")]
public override int Method2()
{
return base.Method2();
}
and it works but it doesn't seem really pretty to me, the main reason being that it leaves the client free to override the body of the method, which is something I'd rather avoid, and it's also tedious to just repeat return base.Method();.
Is there a cleaner approach to solve this kind of problem? Am I missing something obvious?

There's no other way to do that.
About...
"it's also tedious to just repeat return base.Method();[...]"
...I would say that Visual Studio auto-generates this code for you meaning that it's worth the effort (overriding to apply new attributes).
In fact, it's a core design decision in .NET languages since reflection on attributes provides the method Type.GetCustomAttributes(...) and it has an overload which accepts an input parameter called inherit and see its description:
inherit
Type: System.Boolean
true to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties
and events [...]
Anyway, I don't find it an unclear way of doing that, since attributes are an implementation detail and this is why you require polymorphism to decorate an inherited member.
Maybe you're looking for something like this (I've invented new C# syntax!):
[AttributeA]
public metadataoverride int MethodA();

Then you should call the method indirect.
Make a wrapper method that does all base code that should not be overridden:
private int MethodInternal() {
// do common stuff here
// original body of Method()
return Method();
}
The body of Method() in the base class is empty, it's just there for the possibility to inject code.
This makes the call of return base.Method() in derieved classes unnecessary.
Example:
Base class
public virtual int Method()
{
// empty
}
Derived class A
[AttributeA]
public override int Method()
{
// no return base.Method() required
return ???
}

Related

Calling a method from the getter of a property

Is there a way I can define a method, that is called in every case, when a getter for any property in a class is called?
The class is a base class, and I want to implement various SubClasses of it, but each one should have in common that regardless of the property that should be accessed by its getter function, an action should be performed before the attribute is returned.
No, not unless you code it into every Getter, or you abandon "Plain Old C# Classes" altogether and construct a data model paradigm based around a read-audited set of data. If you go down that route that you simply have each "data class" being an Dictionary of Get/Set delegates and access its data values through those delegates. Its not an uncommon design, but it no longer follows the OO paradigms.
Example (psuedo code)
public class MonitoredCustomerObject
{
// Assumption that the Get/Set delegates are stored in a simple Tuple.
private Dictionary<string, Tuple<delegate,delegate>> getterSetterDict = new ...
public GetValue(string key)
{
executeMyOnReadCode();
return getterSetterDict[key].Item1();
}
public SetValue(string key)
{
executeMyOnWriteCode();
getterSetterDict[key].Item2();
}
}
You can kind of fake this, or you can write a Fody extension that does it. For example, you can have your base class defined as:
public abstract class MyBaseClass
{
public object MyProperty
{
get
{
RunSomeMethod();
return MyPropertyValue;
}
}
protected abstract object MyPropertyValue { get; }
}
Which "kind of" forces the implementer to write it like:
public class MyDerivedClass : MyBaseClass
{
protected override object MyPropertyValue
{
get
{
return SomeObjectValue();
}
}
}
The derived class can still hide the base class properties with new, but at least that causes the developer to explicitly realize that they are doing something unintended.

How to define virtual method with return type which is not void in C#

This might sound like a dumb question, but I need to write a virtual method that is being overridden by inherited class. I don't need the virtual method to have any code, since this method is fully dependent on inherited class, therefore all code will be in the override methods.
However, the method has a return type that is not void. If I keep the virtual method empty it would give me an error "no all path return a value".
The only solution I came up with was to implement the virtual method with returning a dummy empty string, but I don't feel this is the best way. Is there any other way to define a virtual method with return type?
Edit:
Even most answers were correct in their own way, they did not help in my case, therefore I am adding snippets of the code which shows why I need to create instance of the base class, and why I can't use interface, or abstract:
//base class
public class Parser
{
public virtual string GetTitle()
{
return "";
}
}
//sub class
public class XYZSite : Parser
{
public override string GetTitle()
{
//do something
return title;
}
}
// in my code I am trying to create a dynamic object
Parser siteObj = new Parser();
string site = "xyz";
switch (site)
{
case "abc":
feedUrl = "www.abc.com/rss";
siteObj = new ABCSite();
break;
case "xyz":
feedUrl = "www.xzy.com/rss";
siteObj = new XYZSite();
break;
}
//further work with siteObj, this is why I wanted to initialize it with base class,
//therefore it won't break no matter what inherited class it was
siteObj.GetTitle();
I know the way I cast Parser object to Site object doesn't seem very optimal, but this is the only way it worked for me, so Please feel free to correct any thing you find wrong in my code.
Edit (Solution)
I followed the advice of many of replies by using interface and abstract. However it only worked for me when I changed the base class to abstract along with all its methods, and inherited the base class from the interface, and then inherited the sub classes from the base class. That way only I could make sure that all classes have the same methods, which can help me generate variant object in runtime.
Public interface IParser
{
string GetTitle();
}
Public abstract class Parser : IParser
{
public abstract string GetTitle();
}
Public class XYZ : Parser
{
public string GetTitle();
{
//actual get title code goes here
}
}
//in my web form I declare the object as follows
IParser siteObj = null;
...
//depending on a certain condition I cast the object to specific sub class
siteObj = new XYZ();
...
//only now I can use GetTitle method regardless of type of object
siteObj.GetTitle();
I am giving the credit to CarbineCoder since he was the one who put enough effort to take me the closest to the right solution. Yet I thank everyone for the contribution.
You can throw NotImplementedException instead of returning object:
public virtual object Method()
{
throw new NotImplementedException();
}
But if you are not implementing anything in virtual method you can create abstract instead of virtual:
public abstract object Method();
Edit:
Another option is to create interface for it.
public interface IMethods
{
object Method();
}
And make your classes children of this interface.
you need to use abstract here. The abstract modifier indicates that the thing being modified has a missing or incomplete implementation.
public abstract returntype MethodName();
But as you say, 'since this method is fully dependent on inherited class, therefore all code will be in the override methods', than if you are really going to override the functionality of the method in inherited class, why do you care if the method returns dummy or stuff? (e.g: you can make it virtual and get going)
Edit: as you cannot mark class as abstract, you can use virtual method instead.
public virtual returntype MethodName()
{
.....
return xyz;
}
(just for info: An abstract member is implicitly virtual. and abstract is sort of pure virtual. so you need virtual, instead of pure virtual)
Since other answers have discussed about abstract/virtual implementation, I am suggesting my own version.
There is a contradiction in your requirement.
You want a base class which is not an abstract but it has a method which is not implemented. Don't you think this unimplemented method will make the class incomplete and end up making it an abstract one even though you haven't explicitly said so?
So lets assume your class will never be an abstract class and its perfectly reasonable to have it as a normal class. Does it make sense to remove this method from the class altogether and move it to an interface?
Can you try extracting this method and put it into an interface.
interface NewInterface
{
string NewMethod();
}
public BaseClass
{
...
}
public DerivedClass : BaseClass, NewInterface
{
public string NewMethod
{
...
}
}
If you can do this, then you need not have to worry about the base class being abstract/ having NotImplemented exception, only downside is every derived class should implement this interface, but thats the point of making the base class non-abstract.
I don't see any problem in implementing Abstract BaseClass/ Interface for your approach. Both are supposed to be the solution for your problem.
//Parser siteObj = new Parser(); - Dont initialize it here,
//your are initializing it once more below
NewIterface siteObj;
string site = "xyz";
switch (site)
{
case "abc":
feedUrl = "www.abc.com/rss";
siteObj = new ABCSite();
break;
case "xyz":
feedUrl = "www.xzy.com/rss";
siteObj = new XYZSite();
break;
}

Call alternative method in class using postsharp

I want to be able to call a differnt method on my intercepted class by using PostSharp.
Say I have the following method in my PostSharp aspect:
public override void OnInvoke(MethodInterceptionArgs args)
{
if (!m_featureToggle.FeatureEnabled)
{
base.OnInvoke(args);
}
else
{
var instance = args.Instance;
instance.CallDifferentMethod(); //this is made up syntax
}
}
The CallDifferentMethod() is another method within the class that has been intercepted. I can do some reflection magic to get the name of what I want to be called, but I can't work out how to call that method on this instance of the class. I don't want to spin up a new instance of the class
Any suggestions?
Are you casting args.Instace to your type? Based on what you wrote, I'd imagine that your "FeatureEnabled" should be defined through an interface.
public interface IHasFeature
{
bool IsFeatureEnabled { get; set; }
void SomeOtherMethod();
}
then use
((IHasFeature)args.Instance).SomeOtherMethod();
Then apply the aspect to that interface.
[assembly: MyApp.MyAspect(AttributeTargetTypes = "MyApp.IHasFeature")]
or on the interface directly
[MyAspect]
public interface IHasFeature
Update: Oops, Gael is right. Sorry about that. Use the CompileTimeValidate method to LIMIT the aspect at compile time.
public override bool CompileTimeValidate(System.Reflection.MethodBase method)
{
bool isCorrectType = (Check for correct type here)
return isCorrectType;
}
For more information, see my post http://www.sharpcrafters.com/blog/post/Day-9-Aspect-Lifetime-Scope-Part-1.aspx

C# Overriding abstract methods (include input parameters)

It is possible in C# do something like this
public absctract class ImportBase()
{
public abstract void CreateDocument();
}
public class UsingOne : ImportBase
{
public override bool CreateDocument(string name)
{
return null;
}
}
I want have some Base class, which only have some methods,but in derived class i need change inputs parameters and inside of method.
You're not overriding the method. The point of having an abstract (or virtual) method is that given any ImportBase, I should be able to call
importBase.CreateDocument();
That's clearly not the case with UsingOne, as it needs more information. So you're really trying to tie your caller to UsingOne, not just ImportBase - at which point you've lost the benefits of polymorphism.
To override a method, the implementation has to have the same signature, basically.
Probably you want to minimize the duplicate code on your derived classes. Basically it's not possible to have an override of a different signature but surely you can refactor your code where you can keep the possible duplicate code in the base class and use it on your derived classes.
public absctract class ImportBase()
{
//Making this protected here
protected virtual void CreateDocument()
{
//Your CreateDocument code
};
}
public class UsingOne : ImportBase
{
private override void CreateDocument()
{
// Override this if you have different CreateDocument for your different
// for different derived class.
}
public bool CreateDocument(string name)
{
// Do whatever you need to do with name parameter.
base.CreateDocument();
// Do whatever you need to do with name parameter.
return true; // return false;
}
}
You can create instance of UsingOne and invoke CreateDocument(string name)
nope. signature must be same on the derived class. i suggest to use builder pattern.
http://en.wikipedia.org/wiki/Builder_pattern

Force base method call

Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..
--edit--
I am mainly curious about overriding methods.
There isn't and shouldn't be anything to do that.
The closest thing I can think of off hand if something like having this in the base class:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
And allow the inheriting class override BeforeFoo and/or AfterFoo
Not in Java. It might be possible in C#, but someone else will have to speak to that.
If I understand correctly you want this:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
What you can do in Java to enforce usage of the superclass foo is something like:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.
Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.
EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.
The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.
This might be useful for scenarios where the method is invoked by some internal API.
i.e. where Foo() is not designed to be invoked directly:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
Works:
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
Yells:
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
Example usage:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
Which produces:
You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super
If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.
No. It is not possible. If you have to have a function that does some pre or post action do something like this:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.
Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.
Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.
EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.
In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
In java, the compiler can only enforce this in the case of Constructors.
A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.
This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.
The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...
There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.
However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.
The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.
Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.
I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.
On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper

Categories

Resources