I have 2 classes:
public class A
{
public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}
public class B : A
{
public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}
In my code I do the following:
B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'
I presumed this would work because of polymorphism.
However, it always writes 'Output from B' every time. Is there anyway to get this to work the way I want it to?
EDIT Fixing code example.
When you "hide" a method from the base class using NEW you are just hiding it, thats it. It's still called when you explicitily call the base class implementation.
A doesnt contain WriteLine so you need to fix that. When I fixed it I got
Output from B
Output
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'
Console.ReadKey();
}
}
public class A
{
public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}
public class B : A
{
public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}
}
Your method on class A is Write, not WriteLine. Change it to the same name and it will work as you expect. I just tried it and get:
Output from B
Output
Polymorphism (C# Programming Guide) explains this quite well. (This is the newer version of the original poster's link.) The page shows examples where a derived class overrides a virtual member and where new members hide base class members.
There appears to be some confusion over the new modifier. From the documentation:
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.
Note that the hidden member does not need to be virtual.
Best practices:
Strongly prefer overriding to hiding. Polymorphic calls are idiomatic in OO languages.
If you intend to hide a member, always use the new modifier.
Never release code with compiler warnings.
If every developer on your team agrees that a compiler warning cannot be fixed, suppress it.
Don't use new keyword when you override the method in class B. And declare the method in A as virtual.
The 'new' keyword is making B's implementation of WriteLine overwrite A's implementation.
Don't accept this as an answer, but in my experience, it's almost always a mistake to use the 'new' keyword in this fashion. It's less readable and muddy's the clarity of your code.
Your class A has a Write function instead of WriteLine
public class A
{
public virtual void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}
public class B : A
{
public override void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}
First: I guess you wanted to name the methods both "WriteLine" but the one in class A is only named "Write". And second: yes you inherit B from A but the object will still be of type "B" so now I don't think what you want is possible.
Related
In my project, I have many DLL assemblies referenced. One of those DLL's contains the bool method that I want to change. I do not have the original source for the DLL and using a Reflector to decompile a project seems impractical. All I want to do is intercept or override this method or method call so that I can change it's return value to match my own method outside of said DLL.
Any such way to do this? Thanks!
Edit:
Here is an example:
public virtual bool isOwner()
{
return false;
}
Essentially, I just want to change getOwner to return true;
If the class is public and the method is marked as virtual, then you can simply override it with this syntax:
public MyClass : TheClass
{
public override ReturnType MethodName(Arguments)
{
//class the base class implementation if needed
//base.MethodName(Arguments)
//do your own stuff and return whatever is needed
}
}
Hope this helps
EDIT: A word of caution though, this won't replace the calling code within the DLL. It will only work if you instantiate the derived class yourself and call it from your code.
Is there a general way to do what you want, built into .NET?
Yes, and no.
If you want every usage of class X' method Y to be replaced by some other code, then no, there is nothing built into .NET class system or compiler that will do this.
If you can inherit from class X, overriding method Y, and then ensure that all places where class X is used, your new class is used instead, then yes, that is the proper way to do this.
This is easily done:
public class YourFixedClass : TheProblematicClass
{
public override string YourProblematicMethod()
{
// probably call the problematic method through base.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
Or, if you can make a new class that implements all the same interfaces, wrapping (delegating) all the methods and properties of the original (problematic) class, then that might be doable, but this requires all actual usage of the class to go through the interfaces.
As this:
public class Wrapper : IInterface1, IInterface2
{
private readonly YourProblematicClass _C;
public Wrapper(YourProblematicClass c)
{
_C = c;
}
public string YourProblematicMetho()
{
// probably call the problematic method through _C.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
If, on the other hand, you don't have control of where all the code is that calls the class/method, then no, you can't do any of this.
So what else is there? Well, there is always the debugger interfaces. You can make a program that is somehow the debugger of itself, patching in the right code upon demand, but this is likely to be extraordinary difficult to get right.
In short, no, there is no way to do what you want. You need to find a different way to accomplish this.
Have you thought about changing the original assembly in the first place? I understand that you don't have the source code for it, but is that because:
You lost it
You didn't make it
In point 1, I would really work towards recreating the source code, either through a decompiler or similar, and get a new project going to fix that.
In point 2, have you thought about contacting the people that made it and asking them for help?
Uhm Ok you can do something like this:
public class MyNameClass : MyDllname.MyClassName
{
public bool isOwner()
{
return !base.isOwner();
}
}
Then you have override the method and you can use all the other methods in the DLL simply using an istance(if there aren't static) of the MyNameClass
You can use "new" modifier.
See example on http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Or this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassA().IsEvenDayToday()); // Result: true
Console.WriteLine(new ClassB().IsEvenDayToday()); // Result: false
Console.ReadKey();
}
}
public class ClassA : ClassB
{
public new bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 == 0;
}
}
public class ClassB
{
public bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 != 0;
}
}
Why does re-sharper want me to not hide a property from an abstract class?
It wants me to use 'new', but is that always preferable?
It seems to imply that hiding a variable so the user can't do base.property is a bad thing.
I'm just a little confused about this OO concept and was wondering if there were strong reasons for or against it.
I have
public abstract class baseClass{
protected string commonProperty {get; set;}
}
public abstract class moreSpecificBaseClass : baseClass {
// Resharper would prefer I use 'new' below
protected string commonProperty = "Some specific setting";
}
public class verySpecificClass : moreSpecificBaseClass {
// Some code
}
From the MSDN documentation:
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.
Hiding class members can lead to misunderstandings and subtle errors. Hence the compiler warns you and requires you to make your intention of a possibly harmful member hiding explicit by using the "new" modifier. This prevents an accidental hiding of a base type member from being unnoticed.
See this little example of how problems can sneak into your code when hiding members:
public abstract class A
{
public int Value = 0;
}
public class B : A
{
// This hides the Value member from the base type A
public new int Value = 0;
}
static void SetValue(B obj, int value)
{
obj.Value = value;
}
static void AddToValue(A obj, int value)
{
obj.Value += value;
}
static void Main(string[] args)
{
B obj = new B();
SetValue(obj, 11);
AddToValue(obj, 5);
Console.Out.WriteLine("obj.Value = " + obj.Value);
Console.Out.WriteLine("((A) obj).Value = " + ((A) obj).Value);
Console.Out.WriteLine("((B) obj).Value = " + ((B) obj).Value);
}
This will output:
obj.Value = 11
((A) obj).Value = 5
((B) obj).Value = 11
Just by looking at the flow of the Main method, you might think that at the end of the method the value of obj.Value is 16 (=11+5). But it isn't - it is even worse: depending on how you access the Value member you will encounter different values.
Now, in this small example, the reason(s) of why the output is not the same and not the expected value in all cases might be easy and quickly to spot. But imagine larger software projects with many classes, lots of inheritances, method arguments being of abstract base class or interface types, 3rd-party class library, you name it..., and the problems caused by hidden members might become much more difficult to identify.
If you don't want the outside world to be able to access the base.property, it should be protected. If it is, you shouldn't be redefining it in a derived class. If it shouldn't be available to the derived class at all, make it private.
It's suggesting new to prevent ambiguity, but in reality you shouldn't be there to begin with.
The reason is that if I do this:
var item = new verySpecificClass();
var val = item.commonProperty;
var basic = (baseClass)item;
if(val == basic.commonProperty)
I'm going to get different results than what a reasonable programmer would expect.
I have a warning at the bottom of my screen:
Warning 1 'WindowsFormsApplication2.EventControlDataSet.Events' hides
inherited member
'System.ComponentModel.MarshalByValueComponent.Events'. Use the new
keyword if hiding was intended. C:\Users\myComputer\Desktop\Event
Control\WindowsFormsApplication2\EventControlDataSet.Designer.cs 112 32 eventControl
If i double click on it, it comes up with:
public EventsDataTable Events {
get {
return this.tableEvents;
}
Can anyone tell me how to get rid of this?
Your class has a base class, and this base class also has a property (which is not virtual or abstract) called Events which is being overridden by your class. If you intend to override it put the "new" keyword after the public modifier. E.G.
public new EventsDataTable Events
{
..
}
If you don't wish to override it change your properties' name to something else.
#wdavo is correct. The same is also true for functions.
If you override a base function, like Update, then in your subclass you need:
new void Update()
{
//do stufff
}
Without the new at the start of the function decleration you will get the warning flag.
In the code below, Class A implements the interface IShow and implements its method ShowData. Class B inherits Class A. In order to use ShowData method in Class B, we have to use keyword new in the ShowData method in order to hide the base class Class A method and use override keyword in order to extend the method.
interface IShow
{
protected void ShowData();
}
class A : IShow
{
protected void ShowData()
{
Console.WriteLine("This is Class A");
}
}
class B : A
{
protected new void ShowData()
{
Console.WriteLine("This is Class B");
}
}
The parent function needs the virtual keyword, and the child function needs the override keyword in front of the function definition.
this warning also triggers when you have: x:Name="Name1" with Text="{Binding Name1}" the Same Property Name in same Element in your <Xaml> which can cause a serious conflict at a certain point when your binding process become more complex.
In C# is it possible to create a function that can only be called from within another function?
e.g., can you do something like this?
private void a()
{
b();
c();
...do something else
private void b()
{
..do something but can only be called from a()
}
private void c()
{
..do something but can only be called from a()
}
}
The reason I want to do this is that function b() and c() split some implentation details of a() and they are just cleaner and easier to read in their own scope. However, these functions are of no use to the class as a() does some handling after they are called which must take place.
Use an anonymous nested function maybe?
I wouldn't worry about taking explicit steps to ensure b() and c() are only called by a().
It makes sense to worry about the public methods you expose on a class, since you're providing an interface to the outside world, potentially to people who don't have access to the source code of your class (or at the very least don't want to worry about the implementation details of your class).
Inside your class, though, you should feel free to have whatever private methods you want for whatever reasons you want. Code re-use is one reason to create a new private method, but creating multiple smaller, single-use methods to break up a larger one is also a perfectly valid (and common) reason.
Beyond that, for future maintainers of your code a simple comment like:
//this method should only be called by a()
private void b()
{
...
}
is going to be far more understandable than most of the other solutions presented here.
Using a delegate you can do:
public voidMyFunction()
{
Func<string> myFunction=(s)=>Console.WriteLine(s);
foreach(string str in myStringList)
{
myFunction(str);
}
}
The short answer is no; however, you can create an anonymous delegate or lambda expression as your internal b() method.
You could use the StackFrame class to check at runtime who's the caller of the function:
public class MyClass
{
public static void A()
{
B();
}
public static void B()
{
var stackTrace = new StackTrace();
if (stackTrace.FrameCount < 1 || stackTrace.GetFrame(1).GetMethod() != typeof(MyClass).GetMethod("A"))
throw new InvalidOperationException("Not called from A()");
}
}
But that is
1) Only at runtime
2) Slow
3) A really dirty hack
Well you could use reflection and just get the calling method name and throw an exception if it were anything other than A.
http://www.csharp-examples.net/reflection-calling-method-name/
But if b and c are private they can only be called from within that class anyway, and if you're the only one that is writing the class, then i fail to see the problem. So it seems to me its not a coding problem but rather one of policy.
I'd just document the intent in the method headers/comments.
Similar Question Here - Note the comments on the answer
Not exactly but you could implement both within their own class. Mark b() as private.
To gain the effect of only a() calling b(), either do as Andrew noted already, by putting a() and b() in a class and marking b() appropriately. If you're working inside of an assembly that you control totally, you could use internal instead of private if a() and b() will be in different classes, but in the same assembly. Then user code cannot call it (from outside of your assembly, that is, from their application program) and you can control via policy the writing of your assembly.
You can also create something like this:
internal abstract class SecretFunctionWrapper
{
private void MySecretFunction()
{
...
}
protected void FunctionWhichCalls()
{
...
MySecretFunction();
}
}
public MyRealClass : SecretFunctionWrapper
{
...
}
This will work only for one function. You can also try nested private class like this:
public class A
{
private static class Wrapped
{
private static void A()
{
secred code
}
public static void B()
{
A();
}
}
public void UsingA()
{
Wrapped.B();
}
}
i dont know but maybe Code by Contracts may help but this is not supported natively
Maybe easier to use #region in this case
You could use the internal keyword and put both those functions inside the same class, while leaving other other functions in a different class:
http://msdn.microsoft.com/en-us/library/7c5ka91b.aspx
In the code below I tried in two ways to access the parent version of methodTwo, but the result was always 2. Is there any way to get the 1 result from a ChildClass instance without modifying these two classes?
class ParentClass
{
public int methodOne()
{
return methodTwo();
}
virtual public int methodTwo()
{
return 1;
}
}
class ChildClass : ParentClass
{
override public int methodTwo()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
var a = new ChildClass();
Console.WriteLine("a.methodOne(): " + a.methodOne());
Console.WriteLine("a.methodTwo(): " + a.methodTwo());
Console.WriteLine("((ParentClass)a).methodTwo(): "
+ ((ParentClass)a).methodTwo());
Console.ReadLine();
}
}
Update ChrisW posted this:
From outside the class, I don't know
any easy way; but, perhaps, I don't
know what happens if you try
reflection: use the Type.GetMethod
method to find the MethodInfo
associated with the method in the
ParentClass, and then call
MethodInfo.Invoke
That answer was deleted. I'm wondering if that hack could work, just for curiosity.
Inside of ChildClass.methodTwo(), you can call base.methodTwo().
Outside of the class, calling ((ParentClass)a).methodTwo() will call ChildClass.methodTwo. That's the whole reason why virtual methods exist.
At the IL level, you could probably issue a call rather than a callvirt, and get the job done - but if we limit ourselves to C# ;-p (edit darn! the runtime stops you: VerificationException: "Operation could destabilize the runtime."; remove the virtual and it works fine; too clever by half...)
Inside the ChildClass type, you can use base.methodTwo() - however, this is not possible externally. Nor can you go down more than one level - there is no base.base.Foo() support.
However, if you disable polymorphism using method-hiding, you can get the answer you want, but for bad reasons:
class ChildClass : ParentClass
{
new public int methodTwo() // bad, do not do
{
return 2;
}
}
Now you can get a different answer from the same object depending on whether the variable is defined as a ChildClass or a ParentClass.
As mentioned above, something is bad with your class design if you need to call "base.base" in PRODUCTION code. But it is quite legitimate to use this technique if you are debugging or searching some workarrounds while using external libraries you cannot compile. It is unpleasant that C# does not provide this option directly. Still you may use Kenneth Xu solution with IL generator and Emit. It works.
class A { public virtual string foo() { return "A"; } }
class B : A { public override string foo() { return "B"; } }
// now in class C
class C : B {}
// we can call virtual method "foo" from A using following code
MethodInfo fooA = typeof(A).GetMethod("foo", BindingFlags.Public | BindingFlags.Instance);
DynamicMethod baseBaseFoo = new DynamicMethod(
"foo_A",
typeof(string),
new[] { typeof(A) },
typeof(A));
ILGenerator il = baseBaseFoo.GetILGenerator();
il.Emit(OpCodes.Ldarg, 0);
il.EmitCall(OpCodes.Call, fooA, null);
il.Emit(OpCodes.Ret);
// call foo() from class A, it returns "A"
(string)baseBaseFoo.Invoke(null, new object[] { this });
For reference and a complete sample see
http://kennethxu.blogspot.cz/2009/05/cnet-calling-grandparent-virtual-method.html
Thank you Kenneth Xu!
As Mark Gravell said, no, not externally. But here's another hack I have used. ChildClass can expose methodTwo() from the ParentClass for its own use or for external use. In your case:
class ChildClass : ParentClass {
override public int methodTwo() {
return 2;
}
public int ParentClass_methodTwo() {
return base.methodTwo();
}
}
// Now instead of
Console.WriteLine("ParentClass methodTwo: " + ((ParentClass)a).methodTwo());
// use
Console.WriteLine("ParentClass methodTwo: " + a.ParentClass_methodTwo());
In my case, the child class introduced the concept of a Peer, and I needed its override of methodTwo() to invoke the base version on the peer. By overridding it, however, it hid it... Or did it? This technique came to the rescue.
class ChildClass : ParentClass {
ChildClass peer;
override public int methodTwo() {
return peer.ParentClass_methodTwo();
}
private int ParentClass_methodTwo() {
return base.methodTwo();
}
}
To my knowledge, once a method has been overridden then you can't call the parent method.
public class Parent
{
public string Method()
{
return "parent";
}
}
public class Child:Parent
{
public string Method()
{
return "child";
}
}
Above code successfully overrides parent method yet value of parent method still unchanged.
You can return values from the Both Parent class and Child class using code below -
Child child = new Child();
string result = (((Parent)child).Method()) + child.Method();
But Visual Studio will show you a warning in Compile Time.
I would think that it is not possible unless you make instance of the ParentClass directly.
Thats the very essense of inheritance, polymorphism...
I stumbled upon this looking for help and ended up with my own approach to calling ancestor versions of a method. This is more of a work-around which assumes you can edit the ancestor class:
Put the functionality in question in the ancestor class into a static method, with the necessary parameters. The method in that class can call it so it need not duplicate the functionality, and the child class can call to that functionality if desired via the static method. That way, it can be done even within a method and can cite which specific class it wants to invoke. Also, it can access farther back ancestors than mere parents, which is the limitation of use "base".