I'm trying add the ability to lookup elements in a List<KeyValuePair<string,int>> by overriding the indexer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class MyList : List<KeyValuePair<string, int>>
{
public int this[string key]
{
get
{
return base.Single(item => item.Key == key).Value;
}
}
}
}
For some reason, the compiler is throwing this error:
'System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string,int>>' does not contain a definition for 'Single'.
While it is true that List<T> doesn't have that method, it should be visible because it is an extension method from the System.Linq namespace (which is included). Obviously using this.Single resolves the issue, but why is access via base an error?
Section 7.6.8 of the C# spec says
When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct.
Which might seem to preclude access to extension method via base. However it also says
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
If base.I is just like ((B)this).I then it seems like extension methods should be allowed here.
Can anyone explain the apparent contradiction in these two statements?
Consider this situation:
public class Base
{
public void BaseMethod()
{
}
}
public class Sub : Base
{
public void SubMethod()
{
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base) { }
}
Here are some interesting assertions about this code:
I cannot call the extension method using ExtensionMethod() from neither Base nor Sub.
I cannot call base.ExtensionMethod() from Sub.
I can call the extension method using Extensions.ExtensionMethod(this) from both Sub and Base.
I can call the extension method using this.ExtensionMethod() from both Sub and Base.
Why is this?
I don't have a conclusive answer, partly because there might not be one: as you can read in this thread, you have to add this. if you want to call it in the extension method style.
When you're trying to use an extension method from the type it is in (or - consequently - from a type that is derived from the type used in the extension method), the compiler doesn't realize this and will try to call it as a static method without any arguments.
As the answer states: they [the language designers] felt it was not an important use case scenario to support implicit extension methods (to give the beast a name) from within the type because it would encourage extension methods that really should be instance methods and it was considered plain unnecessary.
Now, it is hard to find out what is happening exactly under the covers but from some playing around we can deduce that base.X() does not help us. I can only assume that base.X performs its virtual call as X() and not this.X() from the context of the baseclass.
What do I do when I want to call the extension method of a baseclass from a subclass?
Frankly, I haven't found any truly elegant solution. Consider this scenario:
public class Base
{
protected void BaseMethod()
{
this.ExtensionMethod();
}
}
public class Sub : Base
{
public void SubMethod()
{
// What comes here?
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base)
{
Console.WriteLine ("base");
}
public static void ExtensionMethod(this Sub sub)
{
Console.WriteLine ("sub");
}
}
There are 3 ways (leaving aside reflection) to call the ExtensionMethod(Base) overload:
Calling BaseMethod() which forms a proxy between the subclass and the extensionmethod.
You can use BaseMethod(), base.BaseMethod() and this.BaseMethod() for this since now you're just dealing with a normal instance method which in its turn will invoke the extension method. This is a fairly okay solution since you're not polluting the public API but you also have to provide a separate method to do something that should have been accessible in the context in the first place.
Using the extension method as a static method
You can also use the primitive way of writing an extension method by skipping the syntactic sugar and going straight to what it will be compiled as. Now you can pass in a parameter so the compiler doesn't get all confused. Obviously we'll pass a casted version of the current instance so we're targetting the correct overload:
Extensions.ExtensionMethod((Base) this);
Use the - what should be identical translation - of base.ExtensionMethod()
This is inspired by #Mike z's remark about the language spec which says the following:
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
The spec literally says that base.I will be invoked as ((B) this).I. However in our situation, base.ExtensionMethod(); will throw a compilation error while ((Base) this).ExtensionMethod(); will work perfectly.
It looks like something is wrong either in the documentation or in the compiler but that conclusion should be drawn by someone with deeper knowledge in the matter (paging Dr. Lippert).
Isn't this confusing?
Yes, I would say it is. It kind of feels like a black hole within the C# spec: practically everything works flawlessly but then suddenly you have to jump through some hoops because the compiler doesn't know to inject the current instance in the method call in this scenario.
In fact, intellisense is confused about this situation as well:
We have already determined that that call can never work, yet intellisense believes it might. Also notice how it adds "using PortableClassLibrary" behind the name, indicating that a using directive will be added. This is impossible because the current namespace is in fact PortableClassLibrary. But of course when you actually add that method call:
and everything doesn't work as expected.
Perhaps a conclusion?
The main conclusion is simple: it would have been nice if this niche usage of extension methods would be supported. The main argument for not implementing it was because it would encourage people to write extension methods instead of instance methods.
The obvious problem here is of course that you might not always have access to the base class which makes extension methods a must but by the current implementation it is not possible.
Or, as we've seen, not possibly with the cute syntax.
Try to cast the instance to its base class:
((BaseClass)this).ExtensionMethod()
Applied to your code:
public class Base
{
public void BaseMethod()
{
}
}
public static class BaseExtensions
{
public static void ExtensionMethod(this Base baseObj) { }
}
public class Sub : Base
{
public void SubMethod()
{
( (Base) this).ExtensionMethod();
}
}
Related
I use Resharper tool in visual studio
Consider a very simple class written below.
class Test()
{
//constructors do not have any return type.
Test()
{
System.Console.WriteLine("Hello World!");
}
static Test()
{
System.Console.WriteLine("Hello World in Static constructors");
}
public void A()
{
System.Console.WriteLine("A simple function in a class");
}
}
class Program
{
static void Main(string[] args)
{
var asa = new Test(); //Implicitly Typed local variables.
asa.A();
}
}
Using var (the compiler has to infer the type of the variable from the expression on
the right side of the initialization statement).
I have some clarification questions and they are below.
Extra burden to compiler?
How many constructors a class can have?
Why is static constructor called first ? (I checked out by putting a breakpoint?)
Why not Test asa = new Test(); is not preferred by Resharper?
Is it really a good idea to use Resharper first as a beginner? (Myself being a newbie to C and .net programming!)
Thanks in Advance.
Any extra burden to the compiler is basically irrelevant - it should not be part of your decision about whether or not to use var. As noted in comments, it may well require slightly more work for the compiler when you use explicitly declared variable... but again, it's not going to be significant.
A class can have any number of constructors... although it will become unwieldy pretty quickly.
The static constructor will be called once, before the first use of the class (whether that's via a static method or a constructor call). Read the C# spec for more details - section 10.12 of the C# 5 spec includes:
The static constructor for a closed class type executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
An instance of the class type is created.
Any of the static members of the class type are referenced.
You can configure ReSharper to suggest alternatives, or treat them as warnings, etc. Make it work however you think it should, on this front.
Negligible if any. The return type would otherwise be compile checked. You shouldn't base decisions on it, anyhow.
As many as you want as long as they are distinguishable.
Static constructors are part of the type definition. They are invoked when the type is first referenced.
What message are you receiving? R# is configurable.
Edit:
(You can't beat the Skeet).
yes, there is some extra work required, but it is possible to use var keyword only in those situations in which it is pretty easy for the compiler to infer the type.
There is no constraint on number of constructors, but there are some rules constructors have to follow (ie: it needs to be clear for the compiler which constructor to call)
I can't telly you why - let's say this is just one of the rules. The interesting thing is beforefieldinit (http://stackoverflow.com/questions/610818/what-does-beforefieldinit-flag-do, http://csharpindepth.com/Articles/General/Beforefieldinit.aspx)
I personally think that in this case it is just a matter of taste. Some people tend to use var as much as they can, while others do the opposite. I try to use when:
I am working with collections (or it takes a lot of text to tell the compiler about the type: instead of:
Dictionary<<OneOfMyClasses, OtherClasss> dictionary = new Dictionary<OneOfMyClasses, OtherClass>();
I tend to use var:
var dictionary = new Dictionary<OneOfMyClasses, OtherClass>();
Please mind that it doesn't affect readability of the code (i.e. it is still easy to understand what is actually happening).
Thanks Everyone. After some time spent on research, I would like to add some points that might help someone.
Disclaimer:(The following points were derived(or even pasted) from codeproject and other such websites.
1) Every single class can have only one static constructor.
Reason: Static constructor must be parameter-less or simply, constructor overloading is not permitted. And since CLR is going to call this constructor, we do not have any control over passing values to this function. As we directly can’t call static constructors, there is no point in having multiple static constructors.
class Test
{
static Test() {...}
static Test(int a) {...} //would throw error as "Static constructor must be parameter less"
}
2) Static constructor should be declared without any access specifier.
Reason: Again CLR is going to call the static constructor not any object of the class. Hence, we donot need any access-specifier.
3) Static constructor must operate only on static variables of that class
Reason: Non-static members are specific to the object instance. There is no point in modifying a variable whose value depend/bind to their specific object instance.
4) Why should I use a static constructor ? Give me one good example
Reason: You can use a static constructor, say when you want to log the operations that you are going to perform using that class. MSDN says "A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file".
5) When exactly a static constructor is called ?
Answer: The user has no control on when the static constructor is executed in the program.
.As others and MSDN points out "A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced."
6)When using base class and derived class in C#, when a new instance of a derived class is created, does base class constructor is called first or derived class constructor is called first?
Answer: The base class constructor is called first and then the derived class constructor.
Code example
class DerivedClass : ParentClass
{
public DerivedClass()
{
Console.WriteLine("Derived class constructor!");
}
}
class ParentClass
{
public ParentClass()
{
System.Console.WriteLine("Parent class constructor!");
}
}
class Program
{
static void Main(string[] args)
{
var a = new DerivedClass(); //Implicitly Typed local variables.
}
}
7) Why in your above examples, both constructors have public access specifier ? What if I specify private or do-not specify access specifier at all?
Answer: When you do not specify access specifier(this case, the constructor automatically becomes private) or whenever you use a private access specifier, the class cannot be instantiated. Whenever a class contain one or more private constructors it strictly (!) cannot be instantiated. This type of constructors are called special instance constructor and is generally used when all the members of a class are static methods. (Probably the Math class should be a good example.)
**8)Bonus question on inheritance. Does a class inherit from two different classes ?
Strictly No. C# supports only direct inheritance and ofcourse you can use interfaces.For example,
interface Test
{
void abc();
}
class DerivedClass : ParentClass, Test //Test should not be a class. It can be a interface.
{
public DerivedClass()
{
Console.WriteLine("Derived class constructor!");
}
public void abc()
{
//should be publicly defined!
//non public method could not implement from interface Test
}
}
class ParentClass
{
public ParentClass()
{
System.Console.WriteLine("Parent class constructor!");
}
}
I suspect the answer is no, but I want to know if it is possible to do something like this:
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TSomeInterface>()
// This doesn't compile.
where TSomeClass : TSomeInterface
{
//...
}
}
What I mean to indicate in the above (non-working) example is to constrain TSomeInterface such that it can be any base class, implemented interface, or (if you really want to get fancy) implicit conversion of MyGenericClass.
NOTE:
I suspect that the reason why this was never implemented in C# is that generic constraints are not really meant to be code contracts, which is how I am trying to use them here. I really don't care what type TSomeInterface is, so long as it is implemented by TSomeClass.
So far, I have hacked this together:
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TIntermediateType, TSomeInterface>()
where TIntermediateType : TSomeClass, TSomeInterface
{
//...
}
}
This more or less enforces the constraint that I want (that TSomeClass must inherit from, or in the case of an interface, implement, TSomeInterface), but calling it is very clumsy, because I have to specify TIntermediateType (even though I really want it to evaluate against TSomeClass):
var myGenericInstance = new MyGenericClass<TSomeClass>();
myGenericInstance.MyGenericMethod(TSomeClass, TSomeInterface);
Additionally, the above hack is broken because a caller could in theory specify a subclass of TSomeClass as the first type parameter, where only the subclass implements TSomeInterface.
The reason that I want to do this is that I am writing a fluent factory pattern for a WCF service, and I would like to prevent the caller (at compile time) from trying to create an endpoint with a contract that the service class doesn't implement. I can obviously check this at runtime (WCF in fact does this for me), but I am a big fan of compile-time checking.
Is there a better/more elegant way to achieve what I am after here?
The way I was able to wrap my head around the reason why this doesn't compile is the following:
Consider this program compiles:
class Program {
class Class1 { }
class Class2 { }
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TSomeInterface>() where TSomeClass : TSomeInterface {
}
}
static void Main(string[] args) {
var inst = new MyGenericClass<Class1>();
}
}
Everything is good. The compiler is happy. Now consider I change the Main method:
static void Main(string[] args) {
var inst = new MyGenericClass<Class1>();
inst.MyGenericMethod<Class2>();
}
The compiler will complain that Class1 does not implement Class2. But which line is wrong? The constraint is on the call to MyGenericMethod, but the offending line of code is the creation of MyGenericClass.
In other words, which one gets the red squiggly line?
As discussed in this linked question, you can't use a type parameter that isn't from the current declaration, on the left side of a where clause.
So as suggested by w0lf in that other question, what you can do is provide both types in your interface (rather than method) declaration:
public class MyGenericClass<TSomeClass, TSomeInterface> {
where TSomeClass : TSomeInterface
public void MyGenericMethod() // not so generic anymore :(
{
//...
}
}
That, however, greatly limits your MyGenericMethod and forces your class to declare before-hand what base interface you with to allow.
So another option is to use a static method with more type parameters:
public class MyGenericClass<TSomeClass> {
public static void MyGenericMethod<TSomeClass, TSomeInterface>
(MyGenericClass<TSomeClass> that)
where TSomeClass : TSomeInterface
{
// use "that" instead of this
}
}
Possibly you could make it an extension method to make it appear to the user like an actual method.
Neither of these is exactly what you wanted, but probably better than the intermediate type solution.
As for the reason for why not?, my guess is that it would complicate the compiler without adding enough value. Here's a discussion by Angelika Langer of the same subject but about Java. Although there are significant differences between C# and Java, I think her conclusion might apply here as well:
The bottom line is that the usefulness of lower bounds on type
parameters is somewhat debatable. They would be confusing and perhaps
even misleading when used as type parameters of a generic class. On
the other hand, generic methods would occasionally profit from a type
parameter with a lower bound. For methods, a work-around for the
lack of a lower bound type parameter can often be found. Such a
work-around typically involves a static generic method or a lower
bound wildcard.
She also gives a nice use case, see the link above.
An extension method provides the best solution, though it doesn't totally solve all your concerns.
public class MyGenericClass<TSomeClass>
{
}
public static class MyGenericClassExtensions
{
public static void MyGenericMethod<TSomeClass, TSomeInterface>(this MyGenericClass<TSomeClass> self)
where TSomeClass : TSomeInterface
{
//...
}
}
It is still necessary to specify both types when calling MyGenericMethod, but it prevents the caller from specifying an incorrect type for TSomeClass as is possible with the approach you came up with. With this approach, the method can be called like so:
var myGenericInstance = new MyGenericClass<TSomeClass>();
myGenericInstance.MyGenericMethod<TSomeClass, TSomeInterface>();
It will be a compile error if the type parameter MyGenericClass is declared with does not match the first type parameter to MyGenericMethod.
Since the first type parameter can be inferred by the this argument, it is often possible for the compiler to infer both type parameters if their additional parameters to the method.
Here is some code for the discussion
abstract class ClassA
{
public abstract void StartProcess();
}
class ClassB : ClassA
{
public override void StartProcess()
{
Console.WriteLine("ClassB: Render");
}
}
class ClassC : ClassA
{
public override void StartProcess()
{
base.StartProcess();//This is where the compiler complains
Console.WriteLine("ClassC: Render");
}
}
Before everyone jumps down my throat, let me just say that I'm fully aware of the why it does not. But there are cases where being able to do so would make sense and prevent having to declare the base class's method as virtual but with an empty implementation.
Coming from Delphi background, we could do this in Delphi and used it in our class design. If you made the mistake of calling the abstract method on the base class (at run time) you've got an "Abstract Error".
Then I wished the (Delphi) complier check me before!
Now I wish the (C#) complier would let me do this!
How weird is that?
The Questions:
Could not the complier/Jitter simply ignore such a call and issue a warning instead of error?
Do others see/feel this pain?
The case I have, where I need this is the following:
ClassA is part of a library (no control over this class)
ClassC is generated (kind of like how an ASP.NET page gets compiled or a Razor View gets compiled.
But a user of the library can define a ClassB and then ClassC will descend from ClassB instead of ClassA (when it gets generated). Similar to how ASP.NET pages normally descend from System.Web.UI.Page but if you've defined your own "base" page and other pages in your app now descendant from your base page then the generated class descends from your base page (which is turn descends from System.Web.UI.Page).
I hope that part is clear. Then looking at the code I've presented, I can't get instances of ClassC to call into the implementation of ClassB because the code gen doesn't know to include base.StartProcess().
EDIT
It seem that some people didn't quite get what I've written. So let's say you were writing the code generation part that generates ClassC that descends from ClassA. Well, since the method is anstract (in ClassA) you can't generate the line of code that calls into StartProcess() (because the complier won't allow it). As a result, if anyone define a ClassB, the code generation still won't call base.StartProcess(). This is in fact what happens in ASP.NET MVC views.
Ideally I'd like the compiler to ignore it. It ignore many things like calling dispose on a null reference for example.
I'm trying to have a discussion rather be preached to...
EDIT2
Let's assume we have a hierarchy as shown in the code above and it worked.
The opportunity we have now is that the base class, ClassA could have an implementation (in the future) for StartProcess() descendants would call into it. The only way to do this today is to define the method virtual with no body. But that feels a bit icky to me.
How could it possibly make sense to call base.StartProcess() when that's been declared to be abstract? There can't possibly be an implementation to call, so the compiler prohibits it.
Personally I like seeing errors at compile-time instead of either seeing an error at execution time or making the JITter ignore a call which I've specifically made. What if it returned a value which you assigned to a variable? What should that variable value be if the method doesn't exist?
If ClassC is going to derive from ClassB, then you won't get the problem - because you won't be calling into an abstract base method. But your code declares that it derives directly from ClassA instead, not ClassB. If ClassC is generated, it should be generated to derive from ClassB instead, which would be fine.
Personally I think the compiler is doing exactly the right thing here.
EDIT: Just to make it absolutely clear what I believe the appropriate solutions are:
If you want to be able to call base.M() from any derived class, you should make it a virtual method with a no-op implementation, instead of an abstract method.
If you have a code generator which should generate a call to base.M() only in the situations where it's generating a class whose base class has an implementation of M, then it's up to the code generator to get that right - the language shouldn't make everyone else suffer (by deferring error reporting to execution time, or worse still swallowing that error by simply performing a no-op) just because one tool has been written incorrectly.
I think the downsides of either making it an execution-time error to call an abstract base method or making it a no-op are worse than the issues described in the question.
Now an interesting language feature which could potentially be useful here would be the idea of a virtual method which forced overrides to call the base implementation either before or after the override... in a similar way to how a constructor in a derived class always has to call a constructor in the base class either directly or via another constructor. I strongly suspect that the complexity of such a feature (what would happen to the return value? How would use specify before/after semantics? What about exceptions?) would outweigh the benefits. In simple class hierarchies, the template method pattern can perform the same duty in a simpler way.
I don't think it would make sense to let the compiler compile such code.
On the other side I understand the situation in which you are. The fix should be made on the code generator: it should not generate calls to abstract methods (can be checked using reflection). If you do not have access to the code of the code generator I am afraid you do not have many options...
You could create a facade object that is derived from A but implements all abstract methods as empty virtual ones and manipulate the code generator to use it instead of A.
I see what you mean. Sometimes it might be convenient to just don't care whether a base class method is abstract or not. But, a subclass is already very coupled to its parent class, so much that the compiler knows exactly what calls are valid and issues error messages accordingly. There're no virtual base classes.
What you can do is define an adapter class. Kind of a no-op that will just implement the abstract methods to do nothing. It might not be feasible if they return values and you can't decide what default value to return. You would now derive from the adapter and call its non-abstract methods.
UPDATE
You can solve your "requirement" by using reflection. Instead of this:
base.StartProcess();
You'd use something like this:
this.BaseCall("StartProcess");
This would call StartProcess on your base class only if it's not abstract.
Here's the ugly code to make it work (which also considers parameters and default return values):
public static class BaseExtensions {
public static void BaseCall(this object self, string methodName, params object[] parameters) {
self.BaseCall(methodName, typeof(void), null, parameters);
}
public static T BaseCallWithReturn<T>(this object self, string methodName, T defaultReturn = default(T), params object[] parameters) {
return (T)self.BaseCall(methodName, typeof(T), defaultReturn, parameters);
}
private static object BaseCall(this object self, string methodName, Type returnType, object defaultReturn, object[] parameters) {
var parameterTypes = parameters.Select(p => p.GetType()).ToArray();
if (self.GetType().BaseType == null) return null;
var method = self.GetType().BaseType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
if (method == null || method.IsAbstract) return defaultReturn;
var dm = new DynamicMethod(methodName, returnType, new Type[] { self.GetType() }.Concat(parameterTypes).ToArray(), self.GetType());
var il = dm.GetILGenerator();
PushParameters(il, parameterTypes.Length);
il.Emit(OpCodes.Call, method);
il.Emit(OpCodes.Ret);
return dm.Invoke(null, new object[] { self }.Concat(parameters).ToArray());
}
private static void PushParameters(ILGenerator il, int n) {
il.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < n; ++i) {
switch (i+1) {
case 1: il.Emit(OpCodes.Ldarg_1); break;
case 2: il.Emit(OpCodes.Ldarg_2); break;
case 3: il.Emit(OpCodes.Ldarg_3); break;
default: il.Emit(OpCodes.Ldarg_S, i+1); break;
}
}
}
}
Is it worth it? I'll let you decide.
You are deriving ClassC from ClassA, what would you expect base.StartProcess to actually do?
Do you really mean to derive from ClassB
So I recently ran into this C# statement at work:
public new string SomeFunction(int i)
{
return base.SomeFunction(i);
}
I searched the web but I think I can find a better answer here.
Now, I'm guessing that all this does is return a new string with the same value as the string returned by the call to base.SomeFunction(i)... is this correct?
Also, does this feature exist in other languages (java specifically)?
EDIT:
In my specific case, base.SomeFunction is protected and NOT virtual... does this make a difference? Thanks
No, it means that it's hiding SomeFunction in the base class rather than overriding it. If there weren't a method in the base class with the same signature, you'd get a compile-time error (because you'd be trying to hide something that wasn't there!)
See this question for more information. (I don't think this is a duplicate question, as it's about what "new" is for at all rather than just talking about the warning when it's absent.)
Duplicate example from my answer on that question though, just to save the clickthrough...
Here's an example of the difference between hiding a method and overriding it:
using System;
class Base
{
public virtual void OverrideMe()
{
Console.WriteLine("Base.OverrideMe");
}
public virtual void HideMe()
{
Console.WriteLine("Base.HideMe");
}
}
class Derived : Base
{
public override void OverrideMe()
{
Console.WriteLine("Derived.OverrideMe");
}
public new void HideMe()
{
Console.WriteLine("Derived.HideMe");
}
}
class Test
{
static void Main()
{
Base x = new Derived();
x.OverrideMe();
x.HideMe();
}
}
The output is:
Derived.OverrideMe
Base.HideMe
'new' is the member-hiding keyword. From the docs:
When used as a modifier, the new
keyword explicitly hides a member
inherited from a base class. When you
hide an inherited member, the derived
version of the member replaces the
base-class version. Although you can
hide members without the use of the
new modifier, the result is a warning.
If you use new to explicitly hide a
member, it suppresses this warning and
documents the fact that the derived
version is intended as a replacement.
The intent behind your sample code is to make the function public in the child, even though it was protected in the base. The language doesn't let you make a class member more visible in the child, so this instead declares a new function that happens to have the same name. This hides the base function, but then again, the caller wouldn't have had access to that one in the first place, while this function calls the one in the base.
In short, the code is a bit of a hack, but it does make sense. It's probably a hint that the base might need its functionality refactored, though.
I have just one method that I need several different classes to access and it just seems lame to make a utility class for just one method. The classes that need to use this method are already inheriting an abstract class so I can't use inheritance. What would you guys do in this situation?
[I]t just seems lame to make a utility
class for just one method
Just do it, it will grow. It always does. Common.Utilities or something of that nature is always necessary in any non-trivial solution.
Keep in mind that a class is just a small, focused machine. If the class only has one method then it's just a very small, focused machine. There's nothing wrong with it, and centralizing the code is valuable.
There is a cheat that you can use :-)
Create an Interface that your classes can "implement" but, create an extension method on that interface, your classes then magically get that method without having to call the utility class...
public Interface IDoThisThing {}
public static void DoThisThingImpl(this IDoThisThing dtt)
{
//The Impl of Do this thing....
}
Now on your classes you can just add the IDoThisThing
public class MyClass, MyBaseClass, IDoThisThing
{
//...
}
and they Get that thing :-)
Note, this is only syntatic sugar around effectively a utility class, but it does make the client code very clean (as just appears as a method on your class).
What do you mean you can't use inheritance?
If you write the method in the abstract class, you can also write the implementation (not everything in an abstract class needs to be abstract).
But generally, it's advisable to have some sort of 'GeneralUtils' class; cause you end up with a few of these functions.
I'd need more info to give a definite answer.
However a well-named class with a single well-named method could work wonders for readability (as compared to an inheritance based solution for instance)
Since you use the term utility method, I'd say create a static class with the static method and be done with it.
can use extension methods...
namespace ExtendMe
{
public interface IDecorate { }
public static class Extensions
{
public static void CommonMethod(this IDecorate o) { /* do stuff */ }
}
public class Blah :IDecorate {}
public class Widget : IDecorate {}
class Program
{
static void Main(string[] args)
{
new Blah().CommonMethod();
new Widget().CommonMethod();
}
}
}