On Wed, Oct 8, 2008 at 11:04 PM, Zhou Yong <football...@gmail.com> wrote: > This is an interesting thread in the WPF forum, and I think the OP has > raised some of the great points on the design frauds of WPF.
> Take a look at it.
> My first pet peeve of WPF is the seperation of FrameworkElement and > FrameContentElement which doesn't make sense to me:) how about yours?
>> In all in, WPF is over-engineered in a bad way.
Why do you say that? I've never felt that WPF was over-engineered. It's complicated, for sure, and there are definitely a lot of ways to solve the same problem, but I'm OK with that. What do you specifically have in mind, Yong?
On Wed, Oct 8, 2008 at 11:17 PM, Zhou Yong <football...@gmail.com> wrote: > Lovely use of decorator pattern, but the question here is that why we need > to write this, what if the public API contract of the FE/FCE is changed?
I don't know enough about why they chose to do that to be able to answer that question with any certainty. It's a nuisance to deal with, but I can only assume that it makes sense for some reasons. Do you know why the designers of WPF chose to make that separation?
On Wed, Oct 8, 2008 at 11:23 PM, Zhou Yong <football...@gmail.com> wrote: > So you think the separation of FE/FCE class hierarchy is indispensable and > is a good OO practice to follow?
FrameworkElement (FE) derives from UIElement. FrameworkContentElement (FCE) derives from ContentElement. Since the framework is not built on a language that supports multiple inheritance (and thank god for that!), the divergence was necessary. There are parts of ContentElement that you wouldn't want in every FE and there are parts of UIElement that you wouldn't want in every FCE.
FCE basically exists to support the text formatting engine (which can be found in the MS.Internal.Text namespace). There are a few non-text classes that derive from FCE, but they do this just to be lightweight.
The goal was to make the programming experience for dealing with an FE and FCE as similar as possible. If anything, I think this makes the framework *more* elegant.
You can think of an FCE as having everything an FE has except support for layout/rendering. Of course, this is no small feature and you certainly would not want that kind of overhead in every text element. Imagine the perf if you tried to render every textual stroke using WPF’s layout engine... text is far too complex.
True, it’s weird to see the exact same properties, methods, interfaces, events, etc, defined on two completely different base classes. But I guess my general response is a big shrug. As long as Microsoft is willing to maintain the code, I don’t have a problem with it. (And in truth, much of the code shared between the classes is codegen’d anyway during the build process, so its really not that hard for them to maintain... clever chaps!)
Sidenote: IFE vs. LIFE: A mnemonic we used to use is “LIFE begins at UIElement”. That is to say, every UIElement supports Layout, Input, Focus, and Events. ContentElement gives you everything but the ‘L’. As such, the intersection of functionality between an FE and FCE is the IFE portion.
I recommend creating a helper class if you want to treat the IFE portion of framework objects in a polymorphic manner. It’s easy enough to implement... in fact, you can steal most of the implementation from the internal FrameworkObject class. :-)
> FrameworkElement (FE) derives from UIElement.
> FrameworkContentElement (FCE) derives from ContentElement. Since the
> framework is not built on a language that supports multiple
> inheritance (and thank god for that!), the divergence was necessary.
> There are parts of ContentElement that you wouldn't want in every FE
> and there are parts of UIElement that you wouldn't want in every FCE.
> FCE basically exists to support the text formatting engine (which
> can be found in the MS.Internal.Text namespace). There are a few
> non-text classes that derive from FCE, but they do this just to be
> lightweight.
> The goal was to make the programming experience for dealing with an
> FE and FCE as similar as possible. If anything, I think this makes
> the framework *more* elegant.
> You can think of an FCE as having everything an FE has except
> support for layout/rendering. Of course, this is no small feature and
> you certainly would not want that kind of overhead in every text
> element. Imagine the perf if you tried to render every textual stroke
> using WPF’s layout engine... text is far too complex.
> True, it’s weird to see the exact same properties, methods,
> interfaces, events, etc, defined on two completely different base
> classes. But I guess my general response is a big shrug. As long as
> Microsoft is willing to maintain the code, I don’t have a problem with
> it. (And in truth, much of the code shared between the classes is
> codegen’d anyway during the build process, so its really not that hard
> for them to maintain... clever chaps!)
> Sidenote: IFE vs. LIFE: A mnemonic we used to use is “LIFE begins
> at UIElement”. That is to say, every UIElement supports Layout,
> Input, Focus, and Events. ContentElement gives you everything but the
> ‘L’. As such, the intersection of functionality between an FE and FCE
> is the IFE portion.
> I recommend creating a helper class if you want to treat the IFE
> portion of framework objects in a polymorphic manner. It’s easy
> enough to implement... in fact, you can steal most of the
> implementation from the internal FrameworkObject class. :-)
On Thu, Oct 9, 2008 at 8:26 AM, Dr. WPF <a...@drwpf.com> wrote: > FrameworkElement (FE) derives from UIElement. FrameworkContentElement > (FCE) derives from ContentElement. Since the framework is not built on a > language that supports multiple inheritance (and thank god for that!), the > divergence was necessary. There are parts of ContentElement that you > wouldn't want in every FE and there are parts of UIElement that you wouldn't > want in every FCE.
> FCE basically exists to support the text formatting engine (which can be > found in the MS.Internal.Text namespace). There are a few non-text classes > that derive from FCE, but they do this just to be lightweight.
> The goal was to make the programming experience for dealing with an FE and > FCE as similar as possible. If anything, I think this makes the framework > *more* elegant.
> You can think of an FCE as having everything an FE has except support for > layout/rendering. Of course, this is no small feature and you certainly > would not want that kind of overhead in every text element. Imagine the > perf if you tried to render every textual stroke using WPF's layout > engine... text is far too complex.
> True, it's weird to see the exact same properties, methods, interfaces, > events, etc, defined on two completely different base classes. But I guess > my general response is a big shrug. As long as Microsoft is willing to > maintain the code, I don't have a problem with it. (And in truth, much of > the code shared between the classes is codegen'd anyway during the build > process, so its really not that hard for them to maintain... clever chaps!)
> Sidenote: IFE vs. LIFE: A mnemonic we used to use is "LIFE begins at > UIElement". That is to say, every UIElement supports Layout, Input, Focus, > and Events. ContentElement gives you everything but the 'L'. As such, the > intersection of functionality between an FE and FCE is the IFE portion.
> I recommend creating a helper class if you want to treat the IFE portion of > framework objects in a polymorphic manner. It's easy enough to > implement... in fact, you can steal most of the implementation from the > internal FrameworkObject class. :-)
-> I recommend creating a helper class if you want to treat the IFE portion of framework objects in a polymorphic manner. It's easy enough to implement... in fact, you can steal most of the implementation from the internal FrameworkObject class. :-)
Not really dude, if something is common, you'd better refactor them into a common interface, right? I think the trick linked by Josh Smith is really clever, and should be included into the framework, because it's not the responsibility of us developers to write that piece of uninteresting code.
-> FrameworkElement (FE) derives from UIElement. FrameworkContentElement (FCE) derives from ContentElement. Since the framework is not built on a language that supports multiple inheritance (and thank god for that!), the divergence was necessary.
FE and FCE achieve different feature set, but it doesn't necessarily mean that both of them don't have common features/operations, and since someone <http://channel9.msdn.com/shows/ARCast.TV/ARCasttv-Juval-Lowy-on-Inter...>has said interface based design is great, why having troubling using interface to define common public API here?
On Thu, Oct 9, 2008 at 2:26 AM, Dr. WPF <a...@drwpf.com> wrote: > FrameworkElement (FE) derives from UIElement. FrameworkContentElement > (FCE) derives from ContentElement. Since the framework is not built on a > language that supports multiple inheritance (and thank god for that!), the > divergence was necessary. There are parts of ContentElement that you > wouldn't want in every FE and there are parts of UIElement that you wouldn't > want in every FCE.
> FCE basically exists to support the text formatting engine (which can be > found in the MS.Internal.Text namespace). There are a few non-text classes > that derive from FCE, but they do this just to be lightweight.
> The goal was to make the programming experience for dealing with an FE and > FCE as similar as possible. If anything, I think this makes the framework > *more* elegant.
> You can think of an FCE as having everything an FE has except support for > layout/rendering. Of course, this is no small feature and you certainly > would not want that kind of overhead in every text element. Imagine the > perf if you tried to render every textual stroke using WPF's layout > engine... text is far too complex.
> True, it's weird to see the exact same properties, methods, interfaces, > events, etc, defined on two completely different base classes. But I guess > my general response is a big shrug. As long as Microsoft is willing to > maintain the code, I don't have a problem with it. (And in truth, much of > the code shared between the classes is codegen'd anyway during the build > process, so its really not that hard for them to maintain... clever chaps!)
> Sidenote: IFE vs. LIFE: A mnemonic we used to use is "LIFE begins at > UIElement". That is to say, every UIElement supports Layout, Input, Focus, > and Events. ContentElement gives you everything but the 'L'. As such, the > intersection of functionality between an FE and FCE is the IFE portion.
> I recommend creating a helper class if you want to treat the IFE portion of > framework objects in a polymorphic manner. It's easy enough to > implement... in fact, you can steal most of the implementation from the > internal FrameworkObject class. :-)
I've been gone for a week folks, so pardon this late reply, but the Doc said something I have to complain about.
On Thu, Oct 9, 2008 at 2:26 AM, Dr. WPF <a...@drwpf.com> wrote: > Since the framework is not built on a language that supports multiple > inheritance (and thank god for that!), the divergence was necessary.
Man, I can't agree with that. Not at all. Just because it could lead to problems in C++ does not make the concept bad. Even in C++, MI is used to great effect with few problems quite frequently. The issues that C++ has with MI (diamond pattern issues, issues with name clashes, etc.) are a design issue with that language, not a general issue with MI. Eiffel has MI and has NO problems. It's sad, actually, that .NET couldn't have learned a few things from Eiffel. MI and DBC are two concepts I *REALLY* wish that we had in .NET.
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
It all begins with one parenthetical remark, doesn’t it? I guess I should just be happy that you are not complaining about my failure to capitalize the ‘g’ in god. ;-)
I totally respect your views on this, Bill. And I don’t think the MI concept is *bad*... I’m just not as convinced as you are that it’s really *good*. My reason for appreciating the current SI model is that it means we just don’t have to deal with various MI problems.
Note that I’m weighing in here with some hesitation because I have long since lost my true passion for the MI vs. SI debate. I currently fall in the SI camp as a result of first-hand experience with most of the known MI issues.
I will certainly give props to Eiffel for its approach to MI. I played with it back in 2004 and I liked the general approach for dealing with things like name clashes. At the same time, I found myself saying /“here we go again”/ when the provided samples would use the redefine subclause without the select subclause, thereby breaking my polymorphic calls on base classes. This is by far, the biggest drawback with MI. It’s not that it doesn’t have the potential to be powerful and useful... it’s that it is so often poorly implemented. (Yes, you can make the same argument about SI, so I don’t base my opinion entirely on this.)
What it ultimately comes down to is this... I have yet to see a cost-benefit analysis of MI in which I was persuaded that the benefits outweigh the costs. I’m aware of the costs first-hand. What is the great benefit that will move me back to the MI camp? I’ve heard the theoretical benefits for the last 20 years, but every practical MI scenario I’ve experienced just reinforces my membership in the SI camp. (It always seems to involve working within some sort of flawed technology like COM.) [Uh-oh.... there's another parenthetical remark that is liable to devolve.]
All that said, I’m not going to rally against Microsoft if they someday decide to bring MI to C#. However, I’m pretty sure it will require some CLS changes. If I recall correctly, when I examined my Eiffel.net classes in reflector, they did not maintain the “is a” relationship for multiple base classes, but were instead flattened. (It’s been a while and maybe such things have been solved, but I’m guessing there are a few issues in the CLR that interfere with true MI support.)
If I had to place a bet, I’d guess that we will never see true MI in .NET just because of its current reputation (deserved or not). Microsoft probably doesn’t perceive the required investment as paying off for a feature that most shops will just avoid using. It would be an uphill battle, for sure, to bring MI back into wide acceptance. Yes, I’m fine with blaming that entirely on C++.
> I've been gone for a week folks, so pardon this late reply, but the Doc said > something I have to complain about. > On Thu, Oct 9, 2008 at 2:26 AM, Dr. WPF <a...@drwpf.com> wrote:
>> Since the framework is not built on a language that supports multiple >> inheritance (and thank god for that!), the divergence was necessary.
> Man, I can't agree with that. Not at all. Just because it could lead to > problems in C++ does not make the concept bad. Even in C++, MI is used to > great effect with few problems quite frequently. The issues that C++ has > with MI (diamond pattern issues, issues with name clashes, etc.) are a > design issue with that language, not a general issue with MI. Eiffel has MI > and has NO problems. It's sad, actually, that .NET couldn't have learned a > few things from Eiffel. MI and DBC are two concepts I *REALLY* wish that we > had in .NET.
> -- > Quidquid latine dictum sit, altum sonatur. > - Whatever is said in Latin sounds profound.
> War is peace. Freedom is slavery. Bugs are features.
I can agree with a lot of what you said. I doubt MI will make it into .NET, as I'm certain it would require CLS changes. Unlike you, I think that's a pity. I've hit MI issues in the past as well, in C++, but I also was able to put it to tremendous use far more often than I ran into problems with it. Why throw out the baby with the bath water?
I've also never had issue with MI in Eiffel. The select issue you point out in Eiffel isn't that bad, really, and could be easily dealt with in a theoretical MI supporting C#. Really, the MI issues have to be dealt with to some degree in C# already, which is why we have explicit interface definitions. MI adds only the diamond pattern issue, which the language can easily enforce best practices on.
Like every language feature, there's room for abuse and misuse leading to disaster. I hate giving up the power of any feature, in the name of "protecting the developer from themselves". Expose the feature in as clean and safe a manner as possible, regardless of whether or not there is still room for the developer to shoot themselves in the foot. After all, they can do that with EVERY feature of any language you want to pick. This is the same reason I support any and all support for dynamic objects and invocation in C#.
In a cost/benefit analysis, I've never been able to consider the costs to outweigh the benefits of MI. You know at compile time when things are "broken", and simply have to find alternative solutions (which must exist, if SI-only languages can exist). On the other side, for me it's a daily (almost hourly) occurrence when using SI-only languages like C# and Java when I swear at being unable to use MI. A mixin solution (possible to implement in .NET with out the need for changing the CLS) would often be enough, but we don't even have that capability. I'm left with tedious aggregation solutions, which work, but except in the simplest of cases is a pain to code and more importantly, maintain. Hard to follow DRY principles when the language doesn't support MI and/or mixins.
So, I guess we get to agree to disagree. :) The lack of MI is the only thing I really think C# got incredibly wrong.
On Tue, Oct 14, 2008 at 4:06 AM, Dr. WPF <a...@drwpf.com> wrote: > It all begins with one parenthetical remark, doesn't it? I guess I should > just be happy that you are not complaining about my failure to capitalize > the 'g' in god. ;-)
> I totally respect your views on this, Bill. And I don't think the MI > concept is *bad*... I'm just not as convinced as you are that it's really > *good*. My reason for appreciating the current SI model is that it means we > just don't have to deal with various MI problems.
> Note that I'm weighing in here with some hesitation because I have long > since lost my true passion for the MI vs. SI debate. I currently fall in > the SI camp as a result of first-hand experience with most of the known MI > issues.
> I will certainly give props to Eiffel for its approach to MI. I played > with it back in 2004 and I liked the general approach for dealing with > things like name clashes. At the same time, I found myself saying *"here > we go again"* when the provided samples would use the redefine subclause > without the select subclause, thereby breaking my polymorphic calls on > base classes. This is by far, the biggest drawback with MI. It's not that > it doesn't have the potential to be powerful and useful... it's that it is > so often poorly implemented. (Yes, you can make the same argument about SI, > so I don't base my opinion entirely on this.)
> What it ultimately comes down to is this... I have yet to see a > cost-benefit analysis of MI in which I was persuaded that the benefits > outweigh the costs. I'm aware of the costs first-hand. What is the great > benefit that will move me back to the MI camp? I've heard the theoretical > benefits for the last 20 years, but every practical MI scenario I've > experienced just reinforces my membership in the SI camp. (It always seems > to involve working within some sort of flawed technology like COM.) > [Uh-oh.... there's another parenthetical remark that is liable to devolve.]
> All that said, I'm not going to rally against Microsoft if they someday > decide to bring MI to C#. However, I'm pretty sure it will require some CLS > changes. If I recall correctly, when I examined my Eiffel.net classes in > reflector, they did not maintain the "is a" relationship for multiple base > classes, but were instead flattened. (It's been a while and maybe such > things have been solved, but I'm guessing there are a few issues in the CLR > that interfere with true MI support.)
> If I had to place a bet, I'd guess that we will never see true MI in .NET > just because of its current reputation (deserved or not). Microsoft > probably doesn't perceive the required investment as paying off for a > feature that most shops will just avoid using. It would be an uphill > battle, for sure, to bring MI back into wide acceptance. Yes, I'm fine with > blaming that entirely on C++.
> > I've been gone for a week folks, so pardon this late reply, but the Doc > said > > something I have to complain about. > > On Thu, Oct 9, 2008 at 2:26 AM, Dr. WPF <a...@drwpf.com> wrote:
> >> Since the framework is not built on a language that supports multiple > >> inheritance (and thank god for that!), the divergence was necessary.
> > Man, I can't agree with that. Not at all. Just because it could lead to > > problems in C++ does not make the concept bad. Even in C++, MI is used > to > > great effect with few problems quite frequently. The issues that C++ has > > with MI (diamond pattern issues, issues with name clashes, etc.) are a > > design issue with that language, not a general issue with MI. Eiffel has > MI > > and has NO problems. It's sad, actually, that .NET couldn't have learned > a > > few things from Eiffel. MI and DBC are two concepts I *REALLY* wish that > we > > had in .NET.
> > -- > > Quidquid latine dictum sit, altum sonatur. > > - Whatever is said in Latin sounds profound.
> > War is peace. Freedom is slavery. Bugs are features.
I'd honestly like to see MI treated the same way as calls to unmanaged code (or direct memory manipulation). If I choose to use it, I mark the code saying I know what the eff I'm doing now get out of my way! For the most part, I don't need MI or unmanaged code, but when I do...I'm grateful that I can drop to unmanaged and infuriated that I can't perform MI. Yes I know that in many cases, using containment vs inheritance is more elegant. But sometimes, you've got to put up the china and let the bull run loose.
Like I said, I wouldn't care if .NET didn't support telling the compiler that it needs to step out the way in some instances. On the other hand, I can see the drawbacks to MI as well for the .NET team. What happens when some psycho derives a control from a TextBox and a RadioButton or a Panel and a TreeView? Which control's template takes precedence? Do we require the person to provide their own Template? In what order should the events tunnel and bubble? How are dependency properties resolved? Even worse is the fact that with multiple inheritance, you can have more than two base classes. So now the team has to be concerned with how every class interacts with every other class. And that graph of interactions grows exponentially.
Again, like I said however, requiring a developer to mark code as unsafe in order to use MI removes the burden from the team to test these interactions and places it on the developer to REALLY know what he's doing.
I'll be honest, more often than not all I really need is mix-in capabilities. It's maddening when you have interfaces like INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo, IEditableObject and others that all require basically identical coding in so many of my own classes. Delegation works, and is what I use for the most part, but that still requires large amounts of grunt work. Just provide me with a mechanism to say IDataErrorInfo should delegate to the _dataErrorInfo member and let me go on with life. That would take care of the VAST majority of cases in which I wish we had MI, and could be easily done at the compiler/language level with no changes to the CLR.
On Tue, Oct 21, 2008 at 10:30 AM, Mike Brown <mbrow...@gmail.com> wrote: > I'd honestly like to see MI treated the same way as calls to unmanaged > code (or direct memory manipulation). If I choose to use it, I mark the code > saying I know what the eff I'm doing now get out of my way! For the most > part, I don't need MI or unmanaged code, but when I do...I'm grateful that I > can drop to unmanaged and infuriated that I can't perform MI. Yes I know > that in many cases, using containment vs inheritance is more elegant. But > sometimes, you've got to put up the china and let the bull run loose.
> Like I said, I wouldn't care if .NET didn't support telling the compiler > that it needs to step out the way in some instances. On the other hand, I > can see the drawbacks to MI as well for the .NET team. What happens when > some psycho derives a control from a TextBox and a RadioButton or a Panel > and a TreeView? Which control's template takes precedence? Do we require the > person to provide their own Template? In what order should the events tunnel > and bubble? How are dependency properties resolved? Even worse is the fact > that with multiple inheritance, you can have more than two base classes. So > now the team has to be concerned with how every class interacts with every > other class. And that graph of interactions grows exponentially.
> Again, like I said however, requiring a developer to mark code as unsafe in > order to use MI removes the burden from the team to test these interactions > and places it on the developer to REALLY know what he's doing.
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
On Tue, Oct 21, 2008 at 10:41 AM, Bill Kempf <weke...@gmail.com> wrote: > I'll be honest, more often than not all I really need is mix-in > capabilities. It's maddening when you have interfaces like > INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo, > IEditableObject and others that all require basically identical coding in so > many of my own classes. Delegation works, and is what I use for the most > part, but that still requires large amounts of grunt work. Just provide me > with a mechanism to say IDataErrorInfo should delegate to the _dataErrorInfo > member and let me go on with life. That would take care of the VAST > majority of cases in which I wish we had MI, and could be easily done at the > compiler/language level with no changes to the CLR.
> On Tue, Oct 21, 2008 at 10:30 AM, Mike Brown <mbrow...@gmail.com> wrote:
>> I'd honestly like to see MI treated the same way as calls to unmanaged >> code (or direct memory manipulation). If I choose to use it, I mark the code >> saying I know what the eff I'm doing now get out of my way! For the most >> part, I don't need MI or unmanaged code, but when I do...I'm grateful that I >> can drop to unmanaged and infuriated that I can't perform MI. Yes I know >> that in many cases, using containment vs inheritance is more elegant. But >> sometimes, you've got to put up the china and let the bull run loose.
>> Like I said, I wouldn't care if .NET didn't support telling the compiler >> that it needs to step out the way in some instances. On the other hand, I >> can see the drawbacks to MI as well for the .NET team. What happens when >> some psycho derives a control from a TextBox and a RadioButton or a Panel >> and a TreeView? Which control's template takes precedence? Do we require the >> person to provide their own Template? In what order should the events tunnel >> and bubble? How are dependency properties resolved? Even worse is the fact >> that with multiple inheritance, you can have more than two base classes. So >> now the team has to be concerned with how every class interacts with every >> other class. And that graph of interactions grows exponentially.
>> Again, like I said however, requiring a developer to mark code as unsafe >> in order to use MI removes the burden from the team to test these >> interactions and places it on the developer to REALLY know what he's doing.
> -- > Quidquid latine dictum sit, altum sonatur. > - Whatever is said in Latin sounds profound.
> War is peace. Freedom is slavery. Bugs are features.
On Tue, Oct 21, 2008 at 11:05 AM, Mike Brown <mbrow...@gmail.com> wrote: > BTW I still would like the ability to define readonly static fields in an > interface as Java allows.
> On Tue, Oct 21, 2008 at 10:41 AM, Bill Kempf <weke...@gmail.com> wrote:
>> I'll be honest, more often than not all I really need is mix-in >> capabilities. It's maddening when you have interfaces like >> INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo, >> IEditableObject and others that all require basically identical coding in so >> many of my own classes. Delegation works, and is what I use for the most >> part, but that still requires large amounts of grunt work. Just provide me >> with a mechanism to say IDataErrorInfo should delegate to the _dataErrorInfo >> member and let me go on with life. That would take care of the VAST >> majority of cases in which I wish we had MI, and could be easily done at the >> compiler/language level with no changes to the CLR.
>> On Tue, Oct 21, 2008 at 10:30 AM, Mike Brown <mbrow...@gmail.com> wrote:
>>> I'd honestly like to see MI treated the same way as calls to unmanaged >>> code (or direct memory manipulation). If I choose to use it, I mark the code >>> saying I know what the eff I'm doing now get out of my way! For the most >>> part, I don't need MI or unmanaged code, but when I do...I'm grateful that I >>> can drop to unmanaged and infuriated that I can't perform MI. Yes I know >>> that in many cases, using containment vs inheritance is more elegant. But >>> sometimes, you've got to put up the china and let the bull run loose.
>>> Like I said, I wouldn't care if .NET didn't support telling the compiler >>> that it needs to step out the way in some instances. On the other hand, I >>> can see the drawbacks to MI as well for the .NET team. What happens when >>> some psycho derives a control from a TextBox and a RadioButton or a Panel >>> and a TreeView? Which control's template takes precedence? Do we require the >>> person to provide their own Template? In what order should the events tunnel >>> and bubble? How are dependency properties resolved? Even worse is the fact >>> that with multiple inheritance, you can have more than two base classes. So >>> now the team has to be concerned with how every class interacts with every >>> other class. And that graph of interactions grows exponentially.
>>> Again, like I said however, requiring a developer to mark code as unsafe >>> in order to use MI removes the burden from the team to test these >>> interactions and places it on the developer to REALLY know what he's doing.
>> -- >> Quidquid latine dictum sit, altum sonatur. >> - Whatever is said in Latin sounds profound.
>> War is peace. Freedom is slavery. Bugs are features.
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.