VB Syntax of Baseclass Inheritance - vb.net

I am wondering what the following snippets code means. Specifically the section: "Of EntityType As {BusinessEntity, New})". I'm a little new to VB inheritance so some of the syntax is a little foregn to me. I understand that a base class is being used to add functionality to all business objects that inherit from it but the syntax is throwing me off a bit. Is there a name for this design pattern?
Public Class AppObjectBase(Of EntityType As {BusinessEntity, New})
Inherits BusinessObject(Of EntityType)
...
...
Public Class NavTreeObj
Inherits NavTree(Of NavTreeEntity)
End Class
Public Class NavTree(Of EntityType As {NavTreeEntity, New})
Inherits AppObjectBase(Of EntityType)
...
...

Do you know what the Of EntityType part on its own means? If not then you should read about generic types. As for the As {BusinessEntity, New} part, that means that EntityType must either be or inherit from the BusinessEntity type and it must also have a parameterless constructor. By specifying those constraints on the generic type parameter, you are able to access members of the BusinessEntity type and also invoke the constructor to create new instances within the method.

Related

How to extend derived classes by defining class(es) that exposes the instance as a property

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.

VB6 Member variable inheritance

I'm having trouble inheriting a (public) variable, let's say
Public Var As ClassThatIsIndependent
The declaration above generates no trouble for itself, however, if i inherit the class that holds it
Implements BaseClass
I get the error "object module needs to implement variable for interface". I've tried these options (both inside ChildClass)
Public Var As ClassThatIsIndependent
and
Public BaseClass_Var As ClassThatIsIndependent
But none of them solves the problem. Any alternative? I'm open to possible Set/Get solutions, however, i'd prefer to maintain Var as a public variable.
Per the Visual Basic 6.0 Programmer's Guide, Polymorphism, Implementing Properties section:
Suppose we give the Animal class an Age property, by adding a Public variable to the Declarations section:
Option Explicit
Public Age As Double
The Procedure drop downs in the code modules for the Tyrannosaur and Flea classes now contain property procedures for implementing the Age property,
…
Using a public variable to implement a property is strictly a convenience for the programmer. Behind the scenes, Visual Basic implements the property as a pair of property procedures.
You must implement both procedures. The property procedures are easily implemented by storing the value in a private data member, as shown here:
Private mdblAge As Double
Private Property Get Animal_Age() As Double
Animal_Age = mdblAge
End Property
Private Property Let Animal_Age(ByVal RHS As Double)
mdblAge = RHS
End Property
The private data member is an implementation detail, so you have to add it yourself.
That is, the "public interface" is exactly the same whether you use a Public variable or define them with Property Get/Let. And to implement a property in an interface, you can't use the Public variable approach and need to use the Property Get/Let syntax and handle the data storage for it in your own private variables.

Why can't I cast a generic parameter with type constraint to the constrained type?

I am getting used to using interfaces, generics and develping them using inheritance in a real envrionment whilst trying use and implement this into a new architecture for one of our upcoming projects and I have a question regarding generics which I am confused about.
This is more of a educational question for myself because I can't understand why .NET doesn't allow this.
If I have a generic class which is (Of T As IA, T2 As A) then I have the following interfaces and class which implements the base interface
Public Interface IA
Property A As String
End Interface
Public Interface IB
inherits IA
Property B As String
End Interface
Public Class GenericClass(Of T As IA, T2 As A)
'Should be list of IA?
Public list As New List(Of T)
Public Sub Add()
End Sub
End Class
Because I have made T as IA why in the add method is Dim foo4 As T = New A() not legal when
Dim foo1 As IA = New A()
Dim foo2 As T
Dim foo3 = Activator.CreateInstance(Of T2)()
Dim x As IA = foo2
Dim y As IA = foo3
list.Add(x)
list.Add(y)
All of the above is? This is becoming a learning curve for me with generics etc. but I am just very confused with why I logically can't do this?
EDIT: Sorry forgot Class A and error message please see below
Public Class A
Implements IA
Public Property A As String Implements IA.A
End Class
EDIT 2: Error was typed incorrectly
"Value of type class a cannnot be converted to T"
It's not exactly clear what you're trying to do, but one problem I notice is that you seem to be assuming that a List<TypeThatImplementsIA> is somehow interchangeable with a List<IA>. That is not the case. Imagine that A were a class of flying birds, and IA were implemented by creatures that can fly, and someone created a GenericClass<Airplane, BlueJay). Even though Airplane and BlueJay are both things that can fly, one would not be able to add a BlueJay to a List<Airplane>. The one common situation in the Framework where one can use a GenericType<DerivedType> as a GenericType<BaseType> is with IEnumerable<T>. The reason for that is that one can't store T's into an IEnumerable<T>--one can only read them out. If one is expecting an IEnumerable<Animal> and one is given an IEnumerable<MaineCoonCat>, then every time one expects to read an Animal, one will read an instance of MainCoonCat, which inherits from Animal and may thus substitute for it. This feature of IEnumerable<T> is called covariance.
There's a limitation to such behavior, though, which stems from the fact that there is a difference between using an interface as a type of storage location (variable, parameter, etc.), versus using it as a constraint. For every non-nullable value type, there are actually two related types within the Runtime. One of them is a real value type, which has no concept of inheritance (but can implement interfaces). The other is a heap-object type which derives from ValueType (which in turn derives from Object). Most .net languages will implicitly convert the former type to the latter, and allow code to explicitly convert the latter to the former. Interface-type storage locations can only hold references to heap objects. This is significant because it means that while a struct which implements an interface is convertible to that interface type, that doesn't mean instance of the struct is an instance of that interface type. Covariance works on the premise that every object returned by e.g. an IEnumerable<DerivedType> may be used directly as an instance of BaseType without conversion. Such direct substitutability works with inherited class types, and with interfaces that are implemented by class types. It does not work with interfaces implemented by struct types, or with generics that do not have a class constraint. Adding a class constraint to a generic class type parameter will allow that type parameter to participate in covariance, but may preclude the use of structs as the generic type parameter. Note that unless one has particular reason to expect that an interface will be implemented by structures (as is the case with e.g. IComparable<T>, in many cases it's unlikely that an interface would be implemented by a structure and thus a classconstraint would be harmless).
That's because T is not the interface IA itself. It is one implementation of it.
Suppose that you have another class that implements IA:
Public Class B
Implements IA
Public Property B_A As String Implements IA.A
Public Property OtherProperty as Object
End Class
Then you create a new instance of Generic Class like this:
Dim genericObject as new GenericClass(Of B, A)
So in this case, T now is B, and A cannot be casted to B.
In this case instead, replacing the part of your doubt, a code that would make sense for me:
Dim foo4 As IA = New T()
EDIT due to comment
To be able to instantiate T, it is necessary to declare the New constraint in the type definition. So the generic class declaration would be:
Public Class GenericClass(Of T As {New, IA}, T2 As A)

nHibernate, Automapping and Chained Abstract Classes

I'm having some trouble using nHibernate, automapping and a class structure using multiple chains of abstract classes
It's something akin to this
public abstract class AbstractClassA {}
public abstract class AbstractClassB : AbstractClassA {}
public class ClassA : AbstractClassB {}
When I attempt to build these mappings, I receive the following error
"FluentNHibernate.Cfg.FluentConfigurationException was unhandled
Message: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
Database was not configured through Database method."
However, if I remove the abstract keyword from AbstractClassB, everything works fine. The problem only occurs when I have more than one abstract class in the class hierarchy.
I've manually configured the automapping to include both AbstractClassA and AbstractClassB using the following binding class
public class BindItemBases : IManualBinding
{
public void Bind(FluentNHibernate.Automapping.AutoPersistenceModel model)
{
model.IncludeBase<AbstractClassA>();
model.IncludeBase<AbstractClassB>();
}
}
I've had to do a bit of hackery to get around this, but there must be a better way to get this working. Surely nHibernate supports something like this, I just haven't figured out how to configure it right.
Cheers,
James
Why do you include abstract classes in your AutoMappings, are they presented in the database too? Could you provide the inner exception Fluent throws?
model.IncludeBase<AbstractClassA>();
model.IncludeBase<AbstractClassB>();
With this in place you are trying to map AbstractClassB to the database, which is supposedly not what you want.

Accessing members of the other half of a partial class

I'm just learning to work with partial classes in VB.NET and VS2008. Specifically, I'm trying to extend a LINQ to SQL class that was automatically created by SqlMetal.
The automatically generated class looks like this:
Partial Public Class DataContext
Inherits System.Data.Linq.DataContext
...
<Table(Name:="dbo.Concessions")> _
Partial Public Class Concession
...
<Column(Storage:="_Country", DbType:="Char(2)")> _
Public Property Country() As String
...
End Property
...
End Class
In a separate file, here's what I'm trying to do:
Partial Public Class DataContext
Partial Public Class Concession
Public Function Foo() as String
Return DoSomeProcessing(Me.Country)
End Function
End Class
End Class
... but I get blue jaggies under 'Me.Country' and the message 'Country' is not a member of 'DataContext.Concession'. Both halves of the partial class are in the same namespace.
So how do I access the properties of the automatically-generated half of the partial class, from my half of the partial class?
Unless VB.NET generates different stuff in its LINQ to SQL files from C# the classes of the DB tables aren't within the DataContext class, just beside it.
So you have the class MyNamespace.DataContext.Concession when the other half of the partial class is realy MyNamespace.Concession
(This related to VB.NET - might be differences with C# projects)
I put my entities in their own namespace by configuring the Linq-to-SQL model property.
e.g. MyCo.MyProj.Business.Entities
I then add non-Linq business entities in there too, so they are all in the same namespace.
However, when trying to do the above partial class additions, I found that the partial class (i.e. the one you generate, not the auto-generated LINQ class) MUST be in the same project as the Linq-to-SQL model. Otherwise in the Class View and Object Viewer you see two separate classes - seemingly in the same namespace, but not really. Not sure if this is a bug or I am doing something wrong.
But, anyway, putting the partial class file in the same project as your model works.