I'm following along with an excellent Scott Guthrie article (MVC form posting scenarios) and trying to convert it to VB along the way. I've got everything working except one piece. At one point in the article he's adding his own business rules to a LINQ to SQL entity like this:
public partial class Product
{
partial void OnValidate(ChangeAction action)
{
...
}
}
In converting it to VB, I'm not sure how to translate the "partial" part of OnValidate. If I do this:
Partial Public Class Product
Private Sub OnValidate(ByVal action As ChangeAction)
...
End Sub
End Class
then the business rules I put in OnValidate work, but it doesn't throw any exceptions for bad data (i.e. character in a decimal field), which makes sense, since I'm basically overriding Product's validation.
What's the syntax to make sure the underlying class's OnValidate executes in addition to my version?
Edit: Note that making OnValidate "Partial Private Sub" produces the following errors:
Partial methods must have empty method bodies.
Method 'OnValidate' cannot be declared 'Partial' because only one method 'OnValidate' can be marked 'Partial'.
Partial Private Sub OnValidate(ByVal action As ChangeAction)
...
End Sub
As usually happens, the problem lied elsewhere in the code. I had switched from "UpdateModel" to "TryUpdateModel" somewhere along the way, which means simple assignment errors were no longer being thrown. Going back to "UpdateModel" and using "Private Sub OnValidate" as above now works as it should.
OnValidate is already marked as "Partial" in the data context because it is meant to be overridden - I wasn't clobbering the underlying code after all.
marking it as private does the implemetation
'designer'
Partial Class Product
' Definition of the partial method signature.'
Partial Private Sub OnValidate(ByVal action As ChangeAction)
End Sub
End Class
'your implmentation'
Partial Class Product
' Definition of the partial method signature.'
Private Sub OnValidate(ByVal action As ChangeAction)
'do things'
End Sub
End Class
see this http://msdn.microsoft.com/en-us/library/bb531431.aspx
Related
I have a class that I would like to extend by defining a new class that contains the first class as a public property, as well as additional added properties. However, the class that I'm extending has multiple derived types, which should be treated the same in the extension class.
Below is an example of what I am trying to do:
Public Class ClassA
End Class
Public Class ClassB
Inherits ClassA
End Class
Public Class ClassC
Inherits ClassA
End Class
Public Class BaseExtended
Public Property Foo As ClassA
Public Property ExtendedMetaData1 As Double
Public Property ExtendedMetaData12 As Integer
End Class
Public Class DerivedExtendedB
Inherits BaseExtended
Public Property Foo As ClassB
End Class
Public Class DerivedExtendedC
Inherits BaseExtended
Public Property Foo As ClassC
End Class
The code that uses an instance of any of the 'extended' classes would then need use that instance appropriately depending on it's type. There would be many cases where the property 'Foo' needs to be accessed and modified outside of the class that it belongs to.
If I were to implement something like what I have shown above, that would require that I first cast it to the required type before accessing or modifying it. Ideally I would like to do that inside the 'DerivedExtended' class; The alternative, I think, would be to duplicate code to cast that property would [hundreds of times] in the client code.
Private Sub ClientUsesObject(bar As BaseExtended)
' Perform a task that is agnostic Foo type
' Would not require that Foo be cast to any specific type
If bar.GetType() Is GetType(DerivedExtendedB) Then
Dim barCast As DerivedExtendedB = DirectCast(bar, DerivedExtendedB)
' Perform task that requires Foo to be of type ClassB
ElseIf bar.GetType() Is GetType(DerivedExtendedC) Then
Dim barCast As DerivedExtendedC = DirectCast(bar, DerivedExtendedC)
' Perform task that requires Foo to be of type ClassC
End If
End Sub
What I'm looking for is advice outlining or describing a design pattern that can handle this situation. I've searched for quite a while, and have not been able to find any examples that solve this problem.
I realize that this may be somewhat of an "XY" problem. I'm working with existing code that simply assumes all instances are of the same derived type (when in fact some instances are of the other derived type). As such, the existing code does not work. To me what I've tried to outline above seems like the most straightforward path, but I'm open to alternative if this is just the wrong approach.
This pattern of type covariance in derived classes is the canonical reason for what is called in C++ the "Curiously Recurring Template Pattern" and has been called in .NET the "Curiously Recurring Generic Pattern." I believe it's also sometimes referred to as "F-Bounded Polymorphism" (not a computer scientist, so I might have the reference wrong).
You can write a base class like this:
Public Class Base(Of TDerived As Base)
Public Overridable Property foo As TDerived
End Class
And then use it like this:
Public Class MyDerived
Inherits Base(Of MyDerived)
End Class
Then, the derived class has a property foo whose type is MyDerived. No casting required by clients.
However, this has some limitations. It works best when you don't need to switch back and forth between derived and base. There is no one Base, so you can't declare instances of it. If you want to be able to declare something as Base, then you end up needing to fall back on a non-generic base class. This will still work well for certain usage patterns where you don't need to convert from base to derived, but otherwise you run right back into the casting problems you are trying to avoid.
Eric Lippert has written a bit about this pattern. He's always interesting to read, so I'd recommend looking up his commentary.
Another alternative to consider, if the generic approach doesn't work for you, is code generation. You can use T4 templates to process a compact description of what your code should be, and generate the code files from them. A long list of casts is less tedious if you only write the machinery to generate it, you don't write them all out explicitly.
Assume we have a class called "MyClass"
Public Class MyClass
End Class
this class has a function called "My function"
Public Class MyClass
Public Function MyFunction()
End Function
End Class
This class has been implemented for some time and its been working fine. Now we need to change the implementation of the function "MyFunction". One option would be to open the source code and change it there. But I'm guessing there has to be a better approach.
Inheritance comes to mind but I don't want to change the derived classes name. I want the name of the class to still remain "MyClass", But I'm guessing the code below will cause an error:
Public Class MyClass
Inherits MyClass
Public Function MyFunction()
End Function
End Class
In other words I'm trying to create a new version of the old class by keeping most of the members the same but just changing a few functions.
To explain the project as a whole, The program is meant for structural design. What it does it designs structural components (i.e columns, beams, slabs, ...). The design procedures are specified by 3rd parties (government regulations). For example:
In the year 2007 government regulations specified that column dimensions are to satisfy the equation F:
H*B < Fy^2/L
In the year 2008 they introduced a new function G and they say column dimensions must satisfy this new function:
H*B^2 < Fy^0.5/E+Alpha^2/L
Where H and B are column dimensions.
What I don't want to do is to open the source code every year and make these changes. I want to somehow override the functions that need to be changed without opening the source.
Any Ideas?
The code is generally not supposed to be changed over time. That is - if you wrote code that is guaranteed to break after 2 weeks by itself, you probably should reconsider your design.
As you rules/regulations come out, you usually update your input data (in a form of XML, or a relational database for large amounts of data), and your program would automatically pick those up.
The only case you would update your program under this scenario is when new type of regulations come out. But even in this case the changes are usually minimal.
A good anti-pattern example for this - you have 500 forms, each of them has 500 lines of code, so that's 250000 lines of code in your UI layer. New regulations come out that requires changing 50% of the code in each form. Your impact is 125000, which at 40 lines of code per day would take 8.5 developer-years.
A solution to this would be having a change of 100 lines spread across all forms, adding 1 line in each, or leaving everything as is. Also there will be a data load/conversion procedure from a government/other file, which populates your database in the proper format, updating the values or adding new ones. There may be 10 lines of change in that program, but that's about it, 3 days worth of work, if you believe in 40 LoC per day. Otherwise it still falls under 2 weeks of developer's time.
Depending on how you implement it, the benefit of this approach could be that you support old standards as well, so older input can be matched and production reports can be generated. It is a good practice to be able to back-date your reports, cause sometimes there are issues in report code left unnoticed for months before being discovered.
EDIT: A more structured approach to what I suggested in the comments would be storing expression trees in the DB. Most simple form of it is just a linear workflow, using postfix notation (single table). For example A, B, + C - is equivalent to A + B - C. You can then have a user interface for some configuration tool, which only allows user to input values and functions that are applicable. This is assuming applicable values are also stored in DB as parameters (one structural component can have 0...N of them).
Inheritance can do what you want but you need to create a new ancestor, not descendant.
Change the name of the original class to something that denotes that it is a base class. Also, add the MustInherit modifier to the class and Overridable to any of the methods or properties that you may need to override.
One thing to watch for is Private members in this base class. Any members that need to be accessible from the descendant class cannot be Private and must be changed to Protected.
The original class looks like this.
Public MustInherit Class MyBaseClass
Public Overridable Function MyFunction() As String
' code...
End Function
Public Overridable Function AnotherFunction() As String
' code...
End Function
End Class
Now create a new class with the original class's name which inherits from the base class. Override just the members that need to be different.
Public Class MyClass
Inherits MyBaseClass
Public Overrides Function MyFunction() As String
' new code...
End Function
End Class
That will get you started. The Template Pattern will allow you to do more fine grained code changes where only parts of a method need to be changed.
The formula is a bit complicated and you'll still need to change some code unless you store these in a database somehow.
An option would be to use inheritance with a factory method.
Public Class BaseClass
Public MustOverride Function MyFunction()
Public Function GetInstance(ByVal year As Integer) As BaseClass
If year = 2007 Then Return New Class2007()
If Year = 2008 Then Return New Class2008()
End Function
End Class
Public Class Class2007
Inherits BaseClass
Public Overrides Function MyFunction()
' H*B < Fy^2/L
End Function
End Class
Public Class Class2008
Inherits BaseClass
Public Overrides Function MyFunction()
' H*B^2 < Fy^0.5/E+Alpha^2/L
End Function
End Class
then, everywhere in your code you use BaseClass never knowing that Class2007 and Class2008 exists
Dim o As BaseClass
o = BaseClass.GetInstance(2007)
o.MyFunction()
Depending on the need, this can also be done with interface.
If you need to store the formulas in the database as string, you'll need to get a parser and this can also be found using 3rd party library. https://stackoverflow.com/questions/1387430/recommended-math-library-for-c-net
I have been seeing some odd behaviour in an entity that I have for which I created a partial class to override the ToSting Method and provide some basic property setting when a new instance of that entity is created (for example I might set an order date to 'Now') in a constructor.
This odd behaviour led me to look closely at the partial class and I was surprised to see that even when a set of pre existing records was being retrieved the constructor was being called for each retrieved record.
below is a very simple example of what I might have:
Partial Public Class Product
Public Sub New()
CostPrice = 0.0
ListPrice = 0.0
End Sub
Public Overrides Function ToString() As String
Return ProductDescription
End Function
End Class
I have two questions that arise from this:
1) is this normal behaviour in the Entity Framework if you add a partial class to which you add a constructor?
2) if not then I must assume that I have done something wrong, so what would be the correct way to
override the constructor to do things similar to the example I mentioned above?
Thanks for any insights that you can give me.
This is using EF 5.0 in a vb project
think to the sequence of events leading to the retrieval of an entity from the database. Basically it should be something like:
query the database
for each row of the query result give an entity
The giving is then as follow for each retrieved row:
create a new instance of the retrieved entity
populate this new instance with the value of the row
Well with each instance creation, the constructor is called.
I think you are mixing:
instance initialization where you "allocate" the object, and
business initialization where you enforce business logic
both may be done, at least partially, in the constructor.
new is always called when a class is first instantiated and if you do not explicitly declare a constructor then a default constructor will be created by the compiler.
Unless the class is static, classes without constructors are given a public default constructor by the C# compiler in order to enable class instantiation.
When defining POCO classes for Entity Framework the class must have a default constructor and EF will always call this default constructor whether you have explicitly defined it or the compiler did it for you.
If for any reason you have need to pass anything into the class when it is instantiated you can use the ObjectContext.ObjectMaterialized event.
A short example of the problem I have:
Namespace ActivityLogger
Public Class XmlLoggerWriter
Enum XmlLoggerType
Information
Warning
Fault
End Enum
Friend Shared Sub WriteToLog(ByVal Type As XmlLoggerType)
'some code here
End Sub
End Class
End Namespace
And here is the call to the above sub:
Call WriteToLog(ActivityLogger.XmlLoggerWriter.XmlLoggerType.Information)
As you can see, the argument passed is quite lenghty, even though I have imported XML_Writer.ActivityLogger.XmlLoggerWriter.
I was hoping to get just the XmlLoggerType.Information part or even just the Information. Is there any way this can be shorten down? Because this will be used a lot throughout the code, and I like it to be simple and easily readable.
Import also XmlLoggerWriter:
Imports ActivityLogger.XmlLoggerWriter
Then this works:
WriteToLog(XmlLoggerType.Information)
If you also import
Imports ActivityLogger.XmlLoggerWriter.XmlLoggerType
you can even write
WriteToLog(Information)
I am a C# programmer but I have to work with some VB.Net code and I came across a situation where I have two methods on an interface with the same name but different method parameters. When I attempt to implement this interface in a class, VB.Net requires explicitly declaring "Implements MethodName" after the method signature. Since both method names are identical, this is confusing the compiler. Is there a way to get around this sort of problem? I suspect this must be a common occurrence. Any thoughts?
N.B. This was more a case of the programmer not verifying that the interface in question had not changed from underneath him.
How is this confusing the compiler?
The compiler expects to find an implementation for every method signature, and distinguishes the implementations by their signatures.
If the signatures are identical/undistinguishable (in most cases it means that the arguments are of the same types in the same order) you'll get a design-time error related to the interface, saying that the two methods cannot overload eachother as they have the same signature.
So, in any case, the compiler should not be confused.
Should you need further assistance, please attach a code sample - these things are relatively easy to resolve.
Tip: When writing the implementation, as soon as you write down "implements MyInterface" and hit Enter - Visual Studio will create a "skeleton" code of the implementation, which saves you writing the method signatures and correlating them to the interface.
Example code of having two methods with the same name and everythign working well:
Interface MyInterface
Sub MySub(ByVal arg0 As DateTime)
Sub MySub(ByVal arg0 As ULong)
End Interface
Class MyImplementation
Implements MyInterface
Public Sub MySub(ByVal arg0 As Date) Implements MyInterface.MySub
...
End Sub
Public Sub MySub(ByVal arg0 As ULong) Implements MyInterface.MySub
...
End Sub
End Class
You can make the method private and give it another name.
Like:
Private Sub SaveImpl(ByVal someEntity As IEntity) Implements IRepository.Save
this will look to the outside like: someRepository.Save