public class A
{
public virtual string Go(string str) { return str; }
}
public class B : A
{
public override string Go(string str) {return base.Go(str);}
public string Go(IList<string> list) {return "list";}
}
public static void Main(string[] args)
{
var ob = new B();
Console.WriteLine(ob.Go(null));
}
http://dotnetpad.net/ViewPaste/s6VZDImprk2_CqulFcDJ1A
If I run this program I get "list" sent out to the output. Why doesn't this trigger an ambiguous reference error in the compiler?
Since the overload taking a string is not defined in B (only overriden), it has lower precedence than the one taking an IList<string>.
Therefore, the second overload wins and there's no ambiguity.
This is explained in detail in http://csharpindepth.com/Articles/General/Overloading.aspx
Related
If you have a method which is overloaded with a derived type, the method called at run-time depends on the type of your variable, even if the underlying object is actually of the derived type:
class Program
{
static void Main(string[] args)
{
BaseClass theBaseObject = new BaseClass
{
Foo = "FOO"
};
DerivedClass theDerivedObject = new DerivedClass
{
Foo = "FOO",
Bar = "BAR"
};
Processor processor = new Processor();
Console.WriteLine(processor.Compose(theBaseObject));
Console.WriteLine(processor.Compose(theDerivedObject));
Console.WriteLine(processor.Compose((BaseClass) theDerivedObject));
}
}
public class Processor
{
public string Compose(BaseClass item)
{
return item.Foo;
}
public string Compose(DerivedClass item)
{
return Compose((BaseClass)item) + item.Bar;
}
}
public class BaseClass
{
public string Foo { get; set; }
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
}
Actual Output:
FOO
FOOBAR
FOO
I would like to find a way to alter this behaviour such that the most specific method invoked for a given parameter.
Desired output:
FOO
FOOBAR
FOOBAR // because theDerivedObject is an instance of DerivedClass
This would allow specific processing for a bunch of items, all derived from a base.
Is this possible in c#?
Edit:
A clarification - in practice there would be no explicit cast, as the items would likely be in a list of collection of mixed types:
Example using a list without an explicit cast:
foreach (BaseClass item in new []{ theBaseObject, theDerivedObject })
{
Console.WriteLine(processor.Compose(item));
}
Actual output:
FOO
FOO
Desired output:
FOO
FOOBAR
Obviously the cast is still happening - but it's not easy to remove it.
This code reminds me of the Haddocks' Eyes poem:
But I was thinking of a plan
To dye one's whiskers green,
And always use so large a fan
That they could not be seen.
First, your code creates a subclass, but then it casts the object back to the base class, so the compiler cannot see the actual type! The overload in your example is resolved at compile time, so the Compose(BaseClass item) will be called.
You could turn things around and have .NET resolve the overload dynamically for you by hiding all overloads, and exposing a single method that takes a base class and performs a dynamic cast:
public class Processor {
public string Compose(BaseClass item) {
return ComposeImpl((dynamic)item);
}
private string ComposeImpl(BaseClass item) {
return item.Foo;
}
private string ComposeImpl(DerivedClass item) {
return ComposeImpl((BaseClass)item) + item.Bar;
}
}
The "magic" is on this line:
return ComposeImpl((dynamic)item);
the item is cast to dynamic, which tells the system that the actual overload of ComposeImpl must be picked based on the run-time type of the BaseClass object.
First of all the reason you are getting the result you are getting the result you are getting is because of you specifically declared theDerivedObject as DerivedClass therefor it will go DerivedClass as parameter and with (BaseClass) theDerivedObject) you bassically just told the compiler (correct me if im wrong with compiler) or program to take the method with the parameter BaseClass
What you want to do is one of the following options
Number 1:
public class Processor
{
public string Compose(BaseClass item)
{
if (item is DerivedClass)
return Compose((DerivedClass) item);
return item.Foo;
}
public string Compose(DerivedClass item)
{
return item.Foo + item.Bar;
}
}
Number 2
public class Processor
{
public string Compose(BaseClass item)
{
if (item is DerivedClass)
{
var derived = (DerivedClass) item;
return derived.Foo + derived.Bar;
}
return item.Foo;
}
}
Or you might want to overide ToString()
public class Processor
{
public string Compose(BaseClass item)
{
var #class = item as DerivedClass;
return #class?.ToString() ?? item.ToString();
}
}
public class BaseClass
{
public string Foo { get; set; }
public override string ToString()
{
return Foo;
}
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
public override string ToString()
{
return Foo + Bar;
}
}
If you are not using C#6.0 then Processor will be the following
public class Processor
{
public string Compose(BaseClass item)
{
var #class = item as DerivedClass;
if (#class != null)
{
return #class.ToString();
}
return item.ToString();
}
}
public class Processor
{
public string Compose(BaseClass item)
{
return item.Compose();
}
}
public class BaseClass
{
public string Foo { get; set; }
public virtual string Compose()
{
return Foo;
}
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
public override string Compose()
{
return base.Compose() + Bar;
}
}
No wonder you are getting what you get. You overload Compose method. You declare two signatures one for base class, another for derived. Then you call the method several times:
processor.Compose(theBaseObject) calls Compose(BaseClass item)
processor.Compose(theDerivedObject) calls Compose(DerivedClass item). It happens here that several methods might be suitable for the call. Compiler selects a method having closest base class in the hierarchy which is itself DerivedClass.
processor.Compose((BaseClass) theDerivedObject)) calls Compose(BaseClass item) because you've told him to do it. It has no options to chose from.
You've might be interrested in class virtual member overriding. See
public class BaseClass
{
public string Foo { get; set; }
public virtual string GetComposeResult() { return Foo; }
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
public override string GetComposeResult() { return Foo + Bar; }
}
In this case using following code would do what you expect.
public class Processor
{
public string Compose(BaseClass item) { return item.GetComposeResult(); }
}
//Program.cs
public interface TestVal
{
//Input Param
string Input { get; }
//will return output
TestValRes ValidateRe(string input);
}
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}
//TestvalRes.cs
public interface TestvalRes
{
string Input { get; }
bool IsValid { get; }
}
So I just want to pass a string to the TestVal, do validation and call TestvalRes to return whether it is Valid or not, and if Invalid, why? So the validation will be done in the first public interface - TestVal, however I still need to call it inside the Main(), right?
First off, I'd recommend following C# naming conventions and name your interfaces ITestVal and ITestValRes respectively.
Next, static method cannot call instance methods in the same class (without creating an instance and using that). You need to create an instance of the class and pass control of the application flow to that:
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}
I'm new to C#, I'm in doubt about how to make this work:
namespace Core {
public class A{
private reandonly string _var;
public A(string var){
_var=var
}
public GetValue() => return _var;
}
}
using System;
namespace Core.Resources {
public static class B{
public static void DoSomething(){
Console.Writeline($"{A.GetValue()}");
}
}
}
public class C{
static void Main(string args[]){
A a = new A("name");
a.Resources.B.DoSomething();
}
}
A is in main folder, B is in Main/Resources folder, together they make a classlib, Program.cs is using this lib. Is there a way to make this work?
If you write a.Resources you are basically trying to retrieve the member Resources of the class A, which is obviously not defined. Since B is a static class defined in the Core.Resources namespace, all you have to do is to change your code as follows:
public class C
{
public static void Main(string args[])
{
A a = new A("A");
Core.Resources.B.DoSomething();
}
}
or, alternatively, if you don't want to reference the namespace every time:
using Core.Resources;
public class C
{
public static void Main(string args[])
{
A a = new A("A");
B.DoSomething();
}
}
Note that if yuu explicitly define a public constructor for A that accepts one or more arguments, the default parameterless constructor is no more available... hence you have to pass a string to the A constructor if you don't want to see an error in your console. Alternatively, you have to rewrite your A class so that it implements a default parameterless compiler, for example:
public class A
{
private reandonly String _var;
public A() : this(String.Empty) { }
public A(String var)
{
_var = var;
}
}
EDIT AS PER OP COMMENTS AND QUESTION CHANGES
public class A
{
private reandonly String _var;
public String Var
{
get { return _var; }
}
public A(String var)
{
_var = var;
}
}
public static class B
{
public static void DoSomething(String text)
{
Console.Writeline(text);
}
}
public class C
{
public static void Main(string args[])
{
A a = new A("name");
B.DoSomething(a.Var);
}
}
Obviously using virtual and override is the normal situation, but does this telecoms'ish example count?
public class Pipe
{
// whole bunch of protected member variables such as bandwidth, latency, download limit
// etc,
public int GetCost()
{
// work out cost based on above
}
}
public class BigFatPipe : Pipe
{
public BigFatPipe()
{
// sets up the member variables one way
}
}
public class CheapestPossiblePipe: Pipe
{
public CheapestPossiblePipe()
{
// sets up the member variables another way
}
}
then you might call
PrintPrice(new BigFatPipe())
PrintPrice(new CheapestPossiblePipe())
public void PrintPrice(Pipe pipe)
{
int a = pipe.GetCost();
....
}
You'll get two different answers. This isn't the most useful example but does it count?
This post here has a useful discussion of what exactly polymorphism is.
I think most definitions do not explicitly state that an object must have virtual functions to be polymorphic - so yes, I think your example counts.
Constructor overloading is a recognized method to implement static polymorphism. While this isn't really constructor overloading, it's close. So yes, I'd call it polymorphism.
This pattern does work, but introducing a bunch of classes will confuse the user uselessly: they will wonder what the classes do differently.
A few factories methods will do the same job and will be easier to understand and maintain:
public class Pipe
{
// whole bunch of private member variables such as bandwidth, latency, download limit
// etc,
public int GetCost()
{
// work out cost based on above
}
public static Pipe MakeBigFatPipe()
{
var result = new Pipe();
// sets up the member variables one way
return result;
}
public static Pipe MakeCheapestPossiblePipe()
{
var result = new Pipe();
// sets up the member variables another way
return result;
}
}
If I were you I would use folowing approach:
public interface IGetCost
{
int GetCost();
}
public class Pipe : IGetCost
{
public int GetCost(){}
}
public class BigFatPipe : IGetCost
{
//aggregation
private readonly Pipe _pipe;
public BigFatPipe(Pipe pipe)
{
_pipe = pipe;
}
public int GetCost() { }
}
public class CheapestPossiblePipe : IGetCost
{
private readonly Pipe _pipe;
public CheapestPossiblePipe(Pipe pipe)
{
_pipe = pipe;
}
public int GetCost() { }
}
public static void PrintPrice(IGetCost obj)
{
int cost = obj.GetCost();
Console.WriteLine(cost);
}
static void Main(string[] args)
{
IGetCost p;
p = new Pipe();
PrintPrice(p);
p = new BigFatPipe();
PrintPrice(p);
p = new CheapestPossiblePipe();
PrintPrice(p);
}
I also need to say that there're two different things - polymorphism and overloading
polymorphism
public class foo
{
public virtual void foo1{/*....*/}
}
public class fooA : foo
{
public override void foo1{/*....*/}
}
public class fooB : foo
{
public new void foo1{/*....*/}
}
public class fooC : foo
{
//new is the default modifier
public void foo1{/*....*/}
}
overloading
public class foo{
public int foo1{/*....*/}
public int foo1(int a){/*....*/}
public int foo1(string a){/*....*/}
public int foo1(int a, string b){/*....*/}
}
If you have a method which is overloaded with a derived type, the method called at run-time depends on the type of your variable, even if the underlying object is actually of the derived type:
class Program
{
static void Main(string[] args)
{
BaseClass theBaseObject = new BaseClass
{
Foo = "FOO"
};
DerivedClass theDerivedObject = new DerivedClass
{
Foo = "FOO",
Bar = "BAR"
};
Processor processor = new Processor();
Console.WriteLine(processor.Compose(theBaseObject));
Console.WriteLine(processor.Compose(theDerivedObject));
Console.WriteLine(processor.Compose((BaseClass) theDerivedObject));
}
}
public class Processor
{
public string Compose(BaseClass item)
{
return item.Foo;
}
public string Compose(DerivedClass item)
{
return Compose((BaseClass)item) + item.Bar;
}
}
public class BaseClass
{
public string Foo { get; set; }
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
}
Actual Output:
FOO
FOOBAR
FOO
I would like to find a way to alter this behaviour such that the most specific method invoked for a given parameter.
Desired output:
FOO
FOOBAR
FOOBAR // because theDerivedObject is an instance of DerivedClass
This would allow specific processing for a bunch of items, all derived from a base.
Is this possible in c#?
Edit:
A clarification - in practice there would be no explicit cast, as the items would likely be in a list of collection of mixed types:
Example using a list without an explicit cast:
foreach (BaseClass item in new []{ theBaseObject, theDerivedObject })
{
Console.WriteLine(processor.Compose(item));
}
Actual output:
FOO
FOO
Desired output:
FOO
FOOBAR
Obviously the cast is still happening - but it's not easy to remove it.
This code reminds me of the Haddocks' Eyes poem:
But I was thinking of a plan
To dye one's whiskers green,
And always use so large a fan
That they could not be seen.
First, your code creates a subclass, but then it casts the object back to the base class, so the compiler cannot see the actual type! The overload in your example is resolved at compile time, so the Compose(BaseClass item) will be called.
You could turn things around and have .NET resolve the overload dynamically for you by hiding all overloads, and exposing a single method that takes a base class and performs a dynamic cast:
public class Processor {
public string Compose(BaseClass item) {
return ComposeImpl((dynamic)item);
}
private string ComposeImpl(BaseClass item) {
return item.Foo;
}
private string ComposeImpl(DerivedClass item) {
return ComposeImpl((BaseClass)item) + item.Bar;
}
}
The "magic" is on this line:
return ComposeImpl((dynamic)item);
the item is cast to dynamic, which tells the system that the actual overload of ComposeImpl must be picked based on the run-time type of the BaseClass object.
First of all the reason you are getting the result you are getting the result you are getting is because of you specifically declared theDerivedObject as DerivedClass therefor it will go DerivedClass as parameter and with (BaseClass) theDerivedObject) you bassically just told the compiler (correct me if im wrong with compiler) or program to take the method with the parameter BaseClass
What you want to do is one of the following options
Number 1:
public class Processor
{
public string Compose(BaseClass item)
{
if (item is DerivedClass)
return Compose((DerivedClass) item);
return item.Foo;
}
public string Compose(DerivedClass item)
{
return item.Foo + item.Bar;
}
}
Number 2
public class Processor
{
public string Compose(BaseClass item)
{
if (item is DerivedClass)
{
var derived = (DerivedClass) item;
return derived.Foo + derived.Bar;
}
return item.Foo;
}
}
Or you might want to overide ToString()
public class Processor
{
public string Compose(BaseClass item)
{
var #class = item as DerivedClass;
return #class?.ToString() ?? item.ToString();
}
}
public class BaseClass
{
public string Foo { get; set; }
public override string ToString()
{
return Foo;
}
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
public override string ToString()
{
return Foo + Bar;
}
}
If you are not using C#6.0 then Processor will be the following
public class Processor
{
public string Compose(BaseClass item)
{
var #class = item as DerivedClass;
if (#class != null)
{
return #class.ToString();
}
return item.ToString();
}
}
public class Processor
{
public string Compose(BaseClass item)
{
return item.Compose();
}
}
public class BaseClass
{
public string Foo { get; set; }
public virtual string Compose()
{
return Foo;
}
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
public override string Compose()
{
return base.Compose() + Bar;
}
}
No wonder you are getting what you get. You overload Compose method. You declare two signatures one for base class, another for derived. Then you call the method several times:
processor.Compose(theBaseObject) calls Compose(BaseClass item)
processor.Compose(theDerivedObject) calls Compose(DerivedClass item). It happens here that several methods might be suitable for the call. Compiler selects a method having closest base class in the hierarchy which is itself DerivedClass.
processor.Compose((BaseClass) theDerivedObject)) calls Compose(BaseClass item) because you've told him to do it. It has no options to chose from.
You've might be interrested in class virtual member overriding. See
public class BaseClass
{
public string Foo { get; set; }
public virtual string GetComposeResult() { return Foo; }
}
public class DerivedClass : BaseClass
{
public string Bar { get; set; }
public override string GetComposeResult() { return Foo + Bar; }
}
In this case using following code would do what you expect.
public class Processor
{
public string Compose(BaseClass item) { return item.GetComposeResult(); }
}