<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx</link><description>Just like drinking and driving, seperately both are fun things, but put them together and we have a situation where loss becomes a likely result Consider this code : Public Class Invoice Public Price As Decimal Shared Operator +( ByVal first As Invoice</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#49963</link><pubDate>Wed, 01 Jun 2005 06:53:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:49963</guid><dc:creator>bill</dc:creator><description>Sorry for asking a dumb question, but what does DirectCast do?&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=49963" width="1" height="1"&gt;</description></item><item><title>re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#34752</link><pubDate>Thu, 03 Feb 2005 13:28:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:34752</guid><dc:creator>bill</dc:creator><description>Ok, this is a rather tricky scenario!  But I think Dan's idea, taken internally as a Protected Overridable Method, called by the +Operator, and then overridden within the Derived Class, should be the ticket:&lt;br&gt;&lt;br&gt;Public Class Invoice&lt;br&gt;    Public Price As Decimal&lt;br&gt;&lt;br&gt;    Shared Operator +(ByVal first As Invoice, ByVal second As Invoice) As Invoice&lt;br&gt;        Return first.Add(second)&lt;br&gt;    End Operator&lt;br&gt;&lt;br&gt;    Protected Overridable Function Add(ByVal addInvoice As Invoice) As Invoice&lt;br&gt;        Dim retVal As New Invoice&lt;br&gt;        retVal.Price = Me.Price + addInvoice.Price&lt;br&gt;        Return retVal&lt;br&gt;    End Function&lt;br&gt;&lt;br&gt;    Public Overrides Function ToString() As String&lt;br&gt;        Return &amp;quot;Invoice Price = &amp;quot; &amp;amp; Me.Price&lt;br&gt;    End Function&lt;br&gt;End Class&lt;br&gt;&lt;br&gt;&lt;br&gt;Public Class ShippingInvoice&lt;br&gt;    Inherits Invoice&lt;br&gt;&lt;br&gt;    Public ShippingCost As Decimal&lt;br&gt;&lt;br&gt;    Shared Shadows Operator +(ByVal first As ShippingInvoice, _&lt;br&gt;                              ByVal second As ShippingInvoice) As ShippingInvoice&lt;br&gt;        Return DirectCast(first.Add(second), ShippingInvoice)&lt;br&gt;    End Operator&lt;br&gt;    Shared Shadows Operator +(ByVal first As Invoice, _&lt;br&gt;                              ByVal second As ShippingInvoice) As Invoice&lt;br&gt;        Return second.Add(first)&lt;br&gt;    End Operator&lt;br&gt;    Shared Shadows Operator +(ByVal first As ShippingInvoice, _&lt;br&gt;                              ByVal second As Invoice) As Invoice&lt;br&gt;        Return first.Add(second)&lt;br&gt;    End Operator&lt;br&gt;&lt;br&gt;    Protected Overrides Function Add(ByVal addInvoice As Invoice) As Invoice&lt;br&gt;        ' Overrides Invoice.Add() which is the Protected, internal implementation&lt;br&gt;        ' for the '+' binary operator.&lt;br&gt;&lt;br&gt;        If TypeOf addInvoice Is ShippingInvoice Then&lt;br&gt;            With DirectCast(addInvoice, ShippingInvoice)&lt;br&gt;                Dim retVal As New ShippingInvoice&lt;br&gt;                retVal.Price = Me.Price + .Price&lt;br&gt;                retVal.ShippingCost = Me.ShippingCost + .ShippingCost&lt;br&gt;                Return retVal&lt;br&gt;            End With&lt;br&gt;        Else&lt;br&gt;            Return MyBase.Add(addInvoice)&lt;br&gt;        End If&lt;br&gt;    End Function&lt;br&gt;&lt;br&gt;    Public Overrides Function ToString() As String&lt;br&gt;        Return &amp;quot;ShippingInvoice Price = &amp;quot; &amp;amp; Me.Price &amp;amp; _&lt;br&gt;               &amp;quot;, ShippingCost = &amp;quot; &amp;amp; Me.ShippingCost&lt;br&gt;    End Function&lt;br&gt;End Class&lt;br&gt;&lt;br&gt;The above seems to do the trick.  It's not necessarily &amp;quot;perfect&amp;quot; in that I really was not sure how to handle mixed-class operations and had to make a choice.  For example, how should one handle BaseClass + DerivedClass?  Should one add them as BaseClass's, or just Throw an Exception on the basis that this has &amp;quot;no valid meaning&amp;quot;?&lt;br&gt;&lt;br&gt;I decided to take a &amp;quot;lowest common denominator&amp;quot; approach and decided to make it legal, but to have the results be interpreted as a sort of &amp;quot;BaseClass.Add()&amp;quot; methodology.  The other approach would be to have it take a &amp;quot;DerivedClass.Add()&amp;quot; methodology, but consider the BaseClass.ShippingCost = 0.  Or maybe just Trow an Exception in a Mixed situation.&lt;br&gt;&lt;br&gt;However, adopting a &amp;quot;DerivedClass.Add()&amp;quot; methodology cannot work in the above as-is since the BaseClass cannot have a clue what to do.  It can't even know to Throw an Exception in a mixed-class scenario, because it can't even know that there is one.  Or can it..?&lt;br&gt;&lt;br&gt;I'll follow-up with an explanation of how to pull that off if anyone is interested...&lt;br&gt;&lt;br&gt;Mike&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=34752" width="1" height="1"&gt;</description></item><item><title>Blog link of the week 01</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#31221</link><pubDate>Sun, 09 Jan 2005 22:10:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:31221</guid><dc:creator>TrackBack</dc:creator><description>Blog link of the week 01&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=31221" width="1" height="1"&gt;</description></item><item><title>Re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30231</link><pubDate>Sat, 08 Jan 2005 17:14:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30231</guid><dc:creator>bill</dc:creator><description>Hi Ayende,&lt;br&gt;&lt;br&gt;This is NOT the same in any other method in .NET, at least not instance methods. What we are looking at here is the issues that arise from operators being shared (aka static), something which may not be obvious from the code that uses the operators but should be obvious from the code that declares the operator.  But if these calls were instance methods then the issue would not arise.&lt;br&gt;&lt;br&gt;Bill.&lt;br&gt;&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30231" width="1" height="1"&gt;</description></item><item><title>Re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30228</link><pubDate>Sat, 08 Jan 2005 17:08:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30228</guid><dc:creator>bill</dc:creator><description>hi Dan,&lt;br&gt;&lt;br&gt;Exactly !!  If they want polymorphic behaviour then they need to use instance methods that are Overridable.  One problem though that you do get with Overridable methods is that the type is that the derived type cannot be represented (strongly typed), for example, let's say we had an Add method :&lt;br&gt;&lt;br&gt;Public Overridable Function Add(value As Invoice) As Invoice&lt;br&gt; &lt;br&gt;When we go to override that in the derived class, the return type remains as Invoice, not ShippingInvoice. SO what happens is as we extend our hierarchy, we are forced to extend the number of methods.  ShippingInvoice becomes:&lt;br&gt;&lt;br&gt;Public Overrides Function Add(value As Invoice) As Invoice&lt;br&gt;&lt;br&gt;Public Overridable Function Add(value As ShippingInvoice) As ShippingInvoice&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;BTW: looks like I need a spell checker on my property/public field declarations &lt;a title="winking smiley" href="#" &gt;&lt;img src="http://billmccarthy.mvps.org/smileys/bw/wink.gif" border="0"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;Bill&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30228" width="1" height="1"&gt;</description></item><item><title>re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30174</link><pubDate>Sat, 08 Jan 2005 12:41:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30174</guid><dc:creator>bill</dc:creator><description>You do realize that this is the same in any other method in .Net as well? And in any other static typing OO language that I know.&lt;br&gt;What you've here is a simple compile time checking, nothing more.&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30174" width="1" height="1"&gt;</description></item><item><title>re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30120</link><pubDate>Sat, 08 Jan 2005 07:12:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30120</guid><dc:creator>bill</dc:creator><description>&amp;quot;ShiipingCost?&amp;quot; &lt;br&gt;&lt;br&gt;You could probably accomplish what you want by providing an overridable instance method (ie, Invoice Invoice.AddTo(Invoice a)), then calling that from the operator in Invoice. Derived classes would redefine that method rather than shadow the operator.&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30120" width="1" height="1"&gt;</description></item><item><title>Re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30063</link><pubDate>Fri, 07 Jan 2005 19:57:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30063</guid><dc:creator>bill</dc:creator><description>Hi Matthew,&lt;br&gt;&lt;br&gt;Operators are Shared, so you can Overload them or hide them with Shadows, but you cannot make them virtual which is what Overrides requires.  It's for this very reason there connot be polymorphism with operators as they are Shared (aka static)&lt;br&gt;&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30063" width="1" height="1"&gt;</description></item><item><title>re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30052</link><pubDate>Fri, 07 Jan 2005 19:13:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30052</guid><dc:creator>bill</dc:creator><description>&lt;a target="_new" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/vboperatoroverloading.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/vboperatoroverloading.asp&lt;/a&gt; may be relevant also...&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30052" width="1" height="1"&gt;</description></item><item><title>re: Polymorphism and Operator Overloading don't mix !</title><link>http://msmvps.com/blogs/bill/archive/2005/01/07/30030.aspx#30048</link><pubDate>Fri, 07 Jan 2005 19:06:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:30048</guid><dc:creator>bill</dc:creator><description>What if you made Operator+ overridable in Invoice and Overrides in ShippingInvoice?&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=30048" width="1" height="1"&gt;</description></item></channel></rss>