Replies: 20 comments
-
That would fundamentally break OOP in a number of different ways. I am unaware of any OOP language that supports something like this (and no, I don't count JavaScript as an OOP language). First, the memory for the object is assigned by the Second, what would happen if you then tried to "downcast" |
Beta Was this translation helpful? Give feedback.
-
And how do you imagine this would this work with constructor parameters? Or interfaces? |
Beta Was this translation helpful? Give feedback.
-
I know this is controversial and there are a lot of things that need to be looked into but it is usable and can add value if it can be done right. You guys both bring up good points in term of limitations that i don't have answers for as i'm just proposing a feature that would be nice to have not posting a plan on how. Maybe it doesn't need to be down casting . Maybe just a finer way of doing composition or mapping. Instead of casting it will copy the car properties into a new instance. I know this is changing the proposal to a new keyword . In short I am aware of the shortcomings and i don't have it all figured out but nonetheless as a feature will add value. We can leave it up to the developer team to figure out. I'm sure async and await was a pain also but it got figured out. |
Beta Was this translation helpful? Give feedback.
-
var premiumCar = new PremiumCar() from myCar; At this point, it becomes a special syntax for something that you could do much better by writing a var premiumCar = new PremiumCar(myCar); No new syntax necessary, you just have to write some boilerplate code. And avoiding that boilerplate code doesn't seem to be worth much to me. |
Beta Was this translation helpful? Give feedback.
-
I'd say that the general use of such a feature would be somewhat limited and there would be potentially tons of scenarios which couldn't be addressed by a single "shotgun" approach to copying all properties. I think it's something better solved via copy constructors and that could be something accomplished through source generators: [CopyConstructor(From = typeof(Car))]
public partial class PremiumCar : Car {
public Navigation Navi { get; set; }
} generates: public partial class PremiumCar : Car {
public PremiumCar(Car prototype) {
this.Engine = prototype.Engine;
this.Wheels = prototype.Wheels;
}
} |
Beta Was this translation helpful? Give feedback.
-
@svick That's the composition i mentioned. You break the principal of not repeating yourself. I know the ways around . Im rather just trying to explore and see if we can come up with something better. |
Beta Was this translation helpful? Give feedback.
-
It's not composition if you copy the values, like in @HaloFour's example above.
Then you should explain what the alternatives are, what their problems are, how does your proposal improve the situation and why it's worth the cost. I don't like repeating myself, but I don't think the solution is a special feature for every possible pattern. (Though one feature that can cover many patterns, like source generators, might be.) |
Beta Was this translation helpful? Give feedback.
-
Generating automatic copy constructors based on copying properties is asking for trouble. Suppose I have these properties: public string Greeting { get; set; }
public string Name {
get { return _name; }
set {
_name = value;
Greeting = $"Hello, {value}!"
}
}
// Then I do:
Name = "Bob";
Greeting = "How's it going, Bob?" You get different results based on the order the copy happens: public MyClass(MyClass m) {
this.Name = m.Name;
this.Greeting = m.Greeting;
// Name == "Bob", Greeting == "How's it going, Bob?"
}
public MyClass(MyClass m) {
this.Greeting = m.Greeting;
this.Name = m.Name;
// Name == "Bob", Greeting == "Hello, Bob!"
} Copying fields is better, but even then you have gotchas like delegate fields. If you copy the delegate then you may be calling a delegate from the original object. If you don't copy it, then it may be uninitialized when it is expected to be initialized after construction. |
Beta Was this translation helpful? Give feedback.
-
I'm not sure how the definition of downcasting meets your proposal besides the syntax of course.
You do realize you can do that with reflection, right? here is a simplistic example:
Usage:
It's also possible to do that with |
Beta Was this translation helpful? Give feedback.
-
@eyalsk Like i said i'm very aware of the work around. I'm proposing a feature not looking for a work around solution to solve a problem. Something like a single keyword, not having to add extra methods. Something universal. Regardless, thank you for your contribution it is an elegant solution. Maybe even turning it into extension method so you don't have to add it on every class. |
Beta Was this translation helpful? Give feedback.
-
This request reminds me of |
Beta Was this translation helpful? Give feedback.
-
It should be enough to look at the workaround and realize that such a feature does not belong in the language. Anything that requires reflection is a dubious proposition for a language feature. And if reflection is used to access private fields and thus break encapsulation then it's even more dubious. |
Beta Was this translation helpful? Give feedback.
-
What do you mean by "a second level of indirection"? There's no such thing. And you can't resize an array just like you can't resize an object. |
Beta Was this translation helpful? Give feedback.
-
https://msdn.microsoft.com/en-us/library/bb348051%28v=vs.110%29.aspx Array resizing works because the object instance that is the array doesn't contain the array data directly like string does (IIRC), but has a pointer to it. |
Beta Was this translation helpful? Give feedback.
-
.NET Arrays cannot be resized. It's a fundamental aspect of .NET. The array object contains the data just like a string object. In fact, strings and arrays are identical in their in memory representation, the only difference is that strings are readonly, unlike
That creates a new array of the required size and copies the data from the old array. |
Beta Was this translation helpful? Give feedback.
-
@orthoxerox and @mikedn .. Something along the same lines in the background would work. |
Beta Was this translation helpful? Give feedback.
-
You're right, var a = new int[100];
var b = a;
Array.Resize(ref a, 100000);
Console.WriteLine(a.Length == b.Length); returns false. I mistakenly believed there was a level of indirection that allowed all references to the array to access the new data. |
Beta Was this translation helpful? Give feedback.
-
If you're talking about a theoretical spec for this feature, then yes, it should. Guaranteeing that safety is a whole other matter, though. But really, downcasting already exists: public void HandlesEvent(BaseFoo obj)
{
var derived = obj as DerivedFoo;
//could be a different derivative of 'BaseFoo'
if (derived == null) return;
//....
} It's just not by way of allocating a new object. Which, by the way, is the actual meaning of OP's own definition:
|
Beta Was this translation helpful? Give feedback.
-
It's one thing to copy array elements and it's a rather different thing to copy arbitrary objects. Objects have private fields that need to be copied. Using reflection to do that might be an option for some kind of "utility" method but it's not an option for a language feature. For the language to offer such a feature it would likely have to automatically generate some copying code in every class, similar to the way C++ automatically generates copy constructors. For example: class A {
private int x;
public A() { }
public A(A a) => x = a.x; // automatically generated
}
class B : A {
private int y;
public B() { }
public B(B b) : base(b) => y = b.y; // automatically generated
public B(A a) : base(a) => y = 42; // user provided
}
class Program {
static void Main() {
A a = new A();
B b = new B(a);
}
} Doable? Likely. But it comes with various complications.
In fact, you'd probably have more chances to convince people if you propose adding copy constructors to C# instead of trying to sell this "downcasting" thing. It has nothing to do with traditional casting because it breaks referential identity. It's really object creation + copying/cloning the state of an existing object. |
Beta Was this translation helpful? Give feedback.
-
@doktrova Yeah, I know that you didn't look for solutions but the point was that at the end, proposals need to be implemented and well, you proposed to enable downcasting but what you really asked is to reuse the cast syntax for copying. Might be a good idea to suggest APIs at the framework level that deal with copying data from one object to another as opposed to a language feature. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Definition of Downcasting:
In class-based programming, downcasting or type refinement is the act of casting a reference of a base class to one of its derived classes.
There are ways to work around downcasting such as Composition(Passing the base class into the constructor of another class) and Mapping the base to the derived type.
Lets say we have two classes:
Let me know what you think.
Beta Was this translation helpful? Give feedback.
All reactions