I have a method:
private double FindPrice<T>(T l_Price_Breaks) where T : ?
{
}
The ? I want to limit to 3 classes X, Y, Z. These three classes inheric from a class called child:
public class X : Child
public class Y : Child
public class Z : Child
Can't I just do :
private double FindPrice<T>(T l_Price_Breaks) where T : Child
{
}
It works but when I try to call this method using the following:
X MyX = new X();
double return = FindPrice(MyX);
I get "There is no implicit conversion from X to Child".
The code works for me with one exception: You have a variable name called return, which does not work, since this is a reserved keyword in c#. Rename it to result.
You can, but you have another bunch of problems with your code, like
Identifier expected; 'return' is a keyword.
Public needs to be public, etc.
If you rewrite your code like this
class GenericTest
{
public class Child { }
public class X : Child { }
public class Y : Child { }
public class Z : Child { }
private double FindPrice<T>(T l_Price_Breaks) where T : Child
{
return 2;
}
private void foobar()
{
X MyX = new X();
double retValue = FindPrice(MyX);
}
}
It compiles fine.
You're missing some essential information like the implementation of FindPrice, but I'll take a guess that you're using Child instead of T in the body of the FindPrice method.
Related
I have the following classes:
public class Base
{
private int x;
public Base(int _x) { x = _x; }
}
public class Derived : Base
{
int y;
public Derived(int _x,int _y) : base(_x) { y = _y; }
}
I want to create a fake 'Derived' object, but to call the original constructor and ignore the base constructor.
How can I do that?
actually I found a solution.
I investigated a little and found out that I can do it with Typemock:
Isolate.Fake.Instance<Derived(Members.CallOriginal,ConstructorWillBe.Called, BaseConstructorWillBe.Ignored);
It allowes me to create a fake object, call the original constructor and ignore the base constructor.
You can't. When instantiating a Derived object, a constructor of Base must run; after all, a Derived instance is also a Base, the logic of creating a Base must be executed somewhere in the process.
You might be confusing not calling the base constructor with the case where it is implicitly called for you; this happends when Base has an accesible default constructor:
public class Base
{
private int x;
public Base() { } //default constructor
public Base(int _x) { x = _x; }
}
Then this is legal:
public class Derived : Base
{
int y;
public Derived(int _y) { y = _y; } //no explicit base() needed.
}
But that's only because the compiler will add the implicit call for you. The real code is:
public class Derived : Base
{
int y;
public Derived(int _y) : base() { y = _y; }
}
This seems like an XY Problem. What are you really trying to do?
Why can't we call the constructor of the base class within the function body of the constructor of a subclass? For example,
public class Baseclass
{
public int X;
public Baseclass () { }
public Baseclass (int x) { this.X = x; }
}
why
public class Subclass : Baseclass
{
public Subclass (int x) : base (x) { }
}
instead of
public class Subclass : Baseclass
{
public Subclass (int x) : { base(x); }
}
or
public class Subclass : Baseclass
{
public Subclass (int x) : { base.Baseclass(x); }
}
My question is more from the perspective of the design of C#, or other similar OO languages such as C++ and Java, which all follow the same design.
Thanks.
Java does not actually allow what you're proposing - while in Java the call to super() is inside the subclass constructor's body it is a compile error if there are any statements before that call:
// This is Java
public class Subclass extends ParentClass {
public Subclass() {
String x = "foo";
super(); // <-- compile error
}
}
Anyway, the reason is because the runtime (and language specification) demands that the state of a superclass be fully-defined prior to any subclass instance code being executed.
A simple thought-experiment will demonstrate why:
// This is C#
public class ParentClass {
protected readonly Int32 x;
public ParentClass() {
this.x = 123;
}
}
public class Subclass : ParentClass {
// Using your proposed idea:
public Subclass() {
Int32 localX = base.x; // get the current value of `ParentClass.x`
base(); // call base constructor
}
}
In the example above, what is the value of localX?
The answer is "undefined" - and C# and the CLR (and Java) are designed to prevent undefined behaviour - whereas C++ is more forgiving, but that doesn't mean you should do it.
By requiring that all base classes are fully initialized before subclasses prevents an entire series of bugs relating to uninitialized data.
I will say one thing, however - there is no formal reason why we should not be able to execute static code prior to calling the parent constructor. We can actually do this in C# but we have to refactor code so it's a static function call via the parent class' constructor parameters, which isn't pretty - nor does it allow data to be passed directly back to the subclass constructor. So I wish we could do something like this:
public class ParentClass {
public ParentClass(String x, Int32 y) {
// ...
}
}
public class Subclass : ParentClass {
private static ComplexObject GetComplexObject() {
// ...
}
public Subclass() {
// All code before `base()` is executed in a static context:
ComplexObject cmplx = GetComplexObject();
base( cmplx.X, cmplx.Y );
}
}
Instead we currently need to do this:
public Subclass()
: base( GetComplexObject().X, GetComplexObject().Y ) {
}
Or use a static factory method with a private constructor:
private Subclass(String x, Int32 y) : base( x, y ) {
}
public static Subclass Create() {
ComplexObject cmplx = GetComplexObject();
return new Subclass( cmplx.X, cmplx.Y );
}
public class Subclass : Baseclass
{
public Subclass (int x) : base (x) { }
}
Yes this one is the correct answer. I've tried java but the syntax of almost c# codes are different. As soon as you call the base class with constructor on your subclass you need to follow the way you code it from the base class;
You may also try this upon instantiating
Baseclass base = new Baseclass(32);
Let s say I got an abstract class A. There I got some inner classes like here:
public abstract class A
{
public InnerOne x;
public InnerTwo y;
public A(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
public class InnerOne
{
public virtual double value(){
return 0;
}
}
public class InnerTwo
{
public virtual double value(){
return 0;
}
}
}
Then I got it's childrens like this one:
public class B: A
{
public B():base(){
}
public class InnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class InnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
So I was think that when I call B constructor like that I will initialize x and y by creating it's inner classes instances. But actually it not works like that. When I call vaule functions like here it returns zeros.
A newobject = new B();
var bv1 = B.x.value();
var bv2 = B.y.value();
Is there way to force B class to initialize it's x and y fields by it's inner class objects (not with objects from parent abstract class) without re-writing it's constructor?
Even though you have defined the classes inside A or B, they are still public and they are accessible outside A or B. Its no different from a class definied outside A or B.
Imagine the same code with the InnerOne and InnerTwo defined outside the class A and B. It will have the same above behavior. Your root of confusion is misunderstanding inner class usage.
Inorder to get 100, inside B you need to explicitly replace the instance of X and Y variables with an instance that overrides those values. Unless you do them you will not get 100.
public class B: A
{
public B():base(){
X = new OverridenInnerOne();
Y = new OverridenInnerTwo();
}
public class OverridenInnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class OverridenInnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
You can do it, but you must change the definition for class A - and it gets super hairy.
Here's A:
public abstract class A<I1, I2>
where I1 : A<I1, I2>.InnerOne, new()
where I2 : A<I1, I2>.InnerTwo, new()
{
public InnerOne x;
public InnerTwo y;
public A()
{
this.x = new I1();
this.y = new I2();
}
public class InnerOne
{
public virtual double value()
{
return 0;
}
}
public class InnerTwo
{
public virtual double value()
{
return 0;
}
}
}
And here's B:
public class B: A<B.InnerOne, B.InnerTwo>
{
public B():base(){ }
public class InnerOne: A<InnerOne, InnerTwo>.InnerOne
{
public override double value()
{
return 100;
}
}
public class InnerTwo: A<InnerOne, InnerTwo>.InnerTwo
{
public override double value()
{
return 100;
}
}
}
B.x and B.y are instances of A.InnerOne and A.InnerTwo, so you're seeing the value returned as 0 as these have nothing to do with B.InnerOne or B.InnerTwo.
The following B constructor would assign x and y to instances of B.InnerOne and B.InnerTwo which would return 100.
public B(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
If you wanted A to work in the way you expect, you'd need to pass the inner types you wanted through from the B constructor and create instances of them in the A constructor, something like:
public B():base(typeof(InnerOne),typeof(InnerTwo)) { ... }
Using Activator.CreateInstance will let you create these types within A's constructor.
Enigmativity's generic solution is better if you always want A used this way, alternatively this way allows you to have multiple constructors for A so you could optionally pass in different types.
The 'inner class' aspect (embedded class definition) only distracts here, it plays no role.
And to answer the question: No, you cannot have 'virtual constructors' that work this way.
There are of course plenty of ways to get 100 instead of 0 as returnvalue but the question is too artificial to suggest one.
Update: This question has been revised to make it clearer. The answers below seem to reflect that this method works well. Hopefully this question can help people who need to add a get or set to an existing property.
Ran into a problem today where I needed to override a base class's get-only property with both a get and set. Current consensus seems to be that this is impossible, but I think that I found a method.
The general idea is to make a new property instead of directly overrideing the old one, then we create a bridge method that overrides the old get method with a call to the new one.
Situation
Here's some code for an arbitrary pre-existing type structure that can't be modified.
public abstract class A
{
public abstract int X { get; }
}
public class B : A
{
public override int X { get { return 0; } }
}
Problem
We'd like to write this code, but it won't compile.
public class C : B // won't compile: X can't have a 'set' method
{
private int _x;
public override int X { get { return _x; } set { _x = value; } }
}
Solution
We write the code we want anyway, but we declare the property to be new instead of override, allowing us to declare a set method.
public class D : C // Same thing, but will compile because X is 'new'
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } } // also 'virtual', unless we want to 'sealed' it.
// Bridge method provides the override functionality:
protected sealed override int XGetter { get { return this.X; } } // 'sealed' because this bridge should always refer to the new 'get' method
}
The extra bridge method, XGetter, provides the override. This is glued to the base class structure using an intermediate layer:
public abstract class C : B //abstract intermediate layer
{
// Override-and-seal the base property's getter.
public sealed override int X { get { return this.XGetter; } }
// Define the bridge property for the new class to override.
protected abstract int XGetter { get; }
}
I think that D is now equivalent to a class inheriting from B while also being able to override in a setter. Is this correct?
Be careful with your solution as it hides the original intent for A and B. That being said, your solution does work, even when casting to base classes.
Example:
D d = new D();
d.X = 2;
B b = d as B;
Assert.AreEqual(2, b.X);
If the base classes can be modified, I recommend using reflection.
UPDATE:
The following is INCORRECT.
No.
public abstract class A
{
public abstract int X { get; }
public int GetXPlusOne()
{
return X + 1;
}
}
You won't change the value of A.X.
var d = new D();
d.X = 10;
d.GetXPlusOne() == 1
By introducing the new property XGetter in your example, you've made the solution more complex than it needs to be. You can introduce the same property and just reverse which property gets the getter and setter.
public abstract class A
{
public abstract int X { get; }
}
public class D : A
{
private int _x;
public sealed override int X { get { return XGetterSetter; } }
public virtual int XGetterSetter { get { return this._x; } set { this._x = value; } }
}
There's just as much code in class D in the above example as there is in your original example. This just eliminates the need for class B and class C from your example.
Semantically, this solution may not be the same. You'd have to set the XGetterSetter property as opposed to the X property. Derived classes of D would also have to override XGetterSetter as opposed to X.
If I have a very simple class like so:
public class Example
{
public int Number { get; set; }
public Example(int numberArg)
{
this.Number = numberArg;
}
}
And I have a derivative class like so:
public class AnotherExample : Example
{
public int DoubleNumber
{
get
{
return this.Number * 2;
}
}
public AnotherExample(int numberArg) : base(numberArg) {}
}
What difference is there, if any, if I use this.Number to refer to the AnotherExample objects base Number property than if I use base.Number to refer to it?
Thanks!
If Number is not overridden there is no difference, as this.Number will resolve correctly in the chain of inheritance.
This also means that calling this.Member in a base class, if overridden in a derived class will again use the inheritance chain and find the derived implementation.
If it has been overridden, using base will always go to the base class's version of that property, whereas this.Number will first go to your overridden version.
If you plan on calling virtual members inside your constructors, please be aware of the general advice around it:
Virtual member call in a constructor
This answer is leaving out the explanation about member hiding as the OP example is simpler than that.
In this case, there is no difference. In case you override it will take the value from the base class instead of the inherited class:
public class Example {
public virtual int Number { get; set; }
public Example(int numberArg) {
this.Number = numberArg;
}
}
public class AnotherExample : Example {
public override int Number
{
get{return 5;}
set{}
}
public int DoubleNumber {
get {
return this.Number * 2; // returns 10
return base.Number * 2 // returns 2 times whatever the value is
}
}
public AnotherExample(int numberArg) : base(numberArg) {}
}
You can have a variable in derived class that has the same name with in the base class.In this case you need to use this and base keywords to avoid ambiguity.For example:
public class Base
{
public int Number = 0;
}
public class Derived : Base
{
public int Number;
public Derived()
{
this.Number = base.Number + 5;
}
}