Replies: 1 comment
-
<aside>
I really hope people aren't doing this. You should be binding the controls to a POCO MVVM class using a BindingSource. </aside> |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
@grwGeo commented on Fri Jun 05 2015
I believe that type extensibility (as in extension methods) is a very useful feature that should be viewed as part of a healthy OOP design and not just as compiler deception or syntactic sugar.
Type extensibility can be expanded to the much anticipated extension properties, extension events, indexers etc and even Interface implementation. This last one would be particularly useful should we need to group types owned by others, in interfaces owned by us (or others).
The main advantage of type extension is the ability to intervene high up in an inheritance chain, adding extra functionality to a multitude of types with just one stroke (e.g. imagine adding a custom property to all windows forms controls with just a few lines of code). And with the addition of implementing interfaces this can be a very powerful tool.
I have personally indirectly implemented extension properties and events, so it should be logically consistent to implement these.
A syntax for all these could be similar to partial classes and this could replace current syntax for extension methods as well. So something like this (interface optional of course):
(Here is code)
The 'this' keyword should give us all properties of the original class plus our extension class.
The scope and visibility of the extension class and its members would be the same as if the class was defined normally without the 'extension' keyword.
Current syntax could also remain as an alternative to avoid unnecessary lines of code for cases where (for example) lots of different single extension methods for different types are defined and gathered in one static class.
@svick commented on Sat Jun 06 2015
I don't think extension interfaces can be implemented reasonably well without CLR support.
The only way I can imagine it would be implemented is if casting to that interface returned some wrapper object. But that would mean
ReferenceEquals
wouldn't work reliably for such objects. E.g.:@grwGeo commented on Sun Jun 07 2015
I believe that since class extensibility is logically consistent, it deserves to be part of OOP and therefore have full CLR support (not compiler deception). This is what my proposal is aimed at.
@grwGeo commented on Sun Jun 07 2015
Readers should understand that this is a two part proposal:
It can be implemented in these two stages and the first stage could be implemented gradually (e.g. an extension class might not support extension events or indexers to start with).
@grwGeo commented on Sun Jun 07 2015
Another useful application of interface extensibility is when the interface might require implementation of an already existing member.
E.g. all controls (or base controls) that already have a 'Caption' property might be extended to implement an 'ICaption' interface (if they don't implement one). This would allow us to group them into ICaption types and work collectively with their Caption property.
This would only require the first line of the proposed syntax and with such one-liners we could "register" a multitude of different base controls (i.e. different hierarchies).
@ufcpp commented on Sun Jun 07 2015
I' m going to implement the same purpose but somewhat different approach by using a Roslyn code fix provider. I call it "MixinGenerator". (but at this time, this repository contains only test cases: some pairs of an original source and the expected generated result, no implementation.)
The code fix, for instance, will generate a code from
to
If a Mixin struct implements an interface, the code fix will generate a class which implements the same interface.
@paulomorgado commented on Wed Jun 10 2015
Just for the benefit of all,. there really isn't such a thing as partial classes. There are partial class definitions; meaning, partial definitions of classes.
@grwGeo commented on Wed Jun 10 2015
You are right for 'partial classes' but I think that for 'extended classes', philosophically speaking, you could argue both ways.
I.e. they are 'an extended definition of a class' but they are also an almost (but not fully) independent class of their own (and they would be in cases where they do not refer to any of the original members). Another way of looking at it is that they are 'portions of classes' as almost independent data constructions.
So the extended 'portion' is attached to the original part.
@grwGeo commented on Wed Jun 10 2015
Extension constructors should also be possible with the restriction that they call an original constructor and of course they do not conflict with the signature of other existing constructors. Something like:
public extension class OtherOwnersNamespace.OtherOwnersClass : ISomeInterface
{
public OtherOwnersClass(an original set of params, plus a new set of params)
: this(an original set of params){ }
}
@Przemyslaw-W commented on Wed Jun 10 2015
@grwGeo what advantage has such extension ctor over factory method?
@grwGeo commented on Thu Jun 11 2015
@Przemyslaw-W The whole aim is to treat an extended type just like a normal class, with all the syntax that pertains to a class and all related intellisense.
Creating such extension constructors would constrain consumers of the class to initialize instances in a specific way, as long as it is consistent with the initialization of the original class.
@grwGeo commented on Thu Jun 11 2015
I don't know any F# but looking online today I am under the impression that it has advanced type extensibility features (more than C#). Is this true?
@HaloFour commented on Thu Jun 11 2015
F# type extensions are really just syntax for either amending a partial class defined in the same module, or for defining extension methods. C# has those same features.
@grwGeo commented on Thu Jun 11 2015
So in F# extending fields (properties?) or other members apart from methods in a different assembly (for example) is not possible.
Thanks for the clarification.
@grwGeo commented on Tue Jun 23 2015
It might also be possible for extended controls to have full VS designer support. This would be an alternative to inheriting and as described above preferable in cases where we intervene high up in the hierarchy. This might be the basis for the CLR version of the Dependency Properties pattern in WPF.
@GSPP commented on Wed Jun 24 2015
So you want to add new fields to existing types, right? This is an important capability. Often, you cannot define the necessary fields directly on some type for reasons of modularity.
For example, WinForms controls often need user data attached to them. They expose the object Control.Tag property which can be used to attach it. That's very specialized, hacky and allows only for a single tag consumer.
For example if your app deals with customers there will be many aspects. The CRM will want different data than some billing application. But ideally all modules would deal with the same customer object instance. For modularity reasons we would not want to add all CRM and billing fields to the customer. Those should be details of the respective modules.
Imagine there were 10 modules operating on customer objects. What a big ball of mud it would be to attach all required data to the customer object. It would need to have an assembly reference to all modules and all modules would need to reference the customer class. That's cyclic, and a mess.
@grwGeo commented on Thu Jun 25 2015
@GSPP The idea behind extension is not about breaking a class into constituent classes (like partial definitions of classes). The idea behind extension is that the original class is generally unaware of the extensions. These extensions can affect the original class only within their scope of visibility. The original class does not need a reference to the assembly or namespace that extends it, only the other way around.
If your billing module needs to extend the original class, what you would do with what the language provides today is probably define a new class (like CustomerBillingData) and associate an instance of that class with an instance of the Customer class. This class could have its own data, its own logic but it can also interact with the Customer class' data and logic too. The Customer class though would not be aware of the CustomerBillingData class and would not be the cause of any interaction.
Now if you had the extension feature available and IF you believed that conceptually the CustomerBillingData class should have been part of the Customer class then you could achieve the exact same thing by extending the Customer class. This would save you the trouble of associating the instances of Customer-CustomerBillingData plus it should make it conceptually easier to use just one class instead of two (i.e. customer.Order would be more appropriate than customer.CustomerBillingData.Order or customerBillingData.Order). The extension would only be visible from within the extension assembly (same as with CustomerBillingData).
Also if you were to serialize your extended data on a database, the Entity Framework could interpret extension classes as separate tables with a 1-1 relationship with the original class.
@GSPP commented on Thu Jun 25 2015
@grwGeo You could define a CustomerBillingData class but you can't pass it through code that only expects a Customer. You can pass in the Customer but you can't get the CustomerBillingData back out. An example would be some kind of session.
With extension fields you could do that.
Beta Was this translation helpful? Give feedback.
All reactions