Die Inhalte auf dieser Seite stehen unter diesem Creative Commens License Dingsbums. Also fröhlich kopieren und weiterverteilen. Bitte abweichende Copyright-Hinweise in anderen Blogs respektiveren.

Donnerstag, 22. April 2010

2010-04-23 Definitions for an application core

Under construction

Some definitions for an application-core under .NET framework using WPF/ORM-Framework/SQL-Server

Lifetime service

The framework supplies object initialization and termination in hirarchically organized ownership models. It can optionally track lifing objects. It manages recursive termination of all child objects when a parent object is terminated.

Service Container features for Dependency Injection [DICont]

The framework supplies various implementations of dependency injection containers to supply services [DiService] identified by a System.Type.

local service dependency injection container [LocalDICont].

This is the most simple implementation of a service container which is just a mapping from an SystemType object representing a service interface to an system.object which represents the service implementing the interface.

virtual services dependency injection container [VirtualDICont].

A special [DiCont] implementation allows to make services available for all child objects. Using this feature services can be routed through object hirarchies from a root-level service provider to a nested-level service user where objects in the middle do not neet do declare code to forward services to child objects. Using this features various dependencies and delegation code can be elimanted.

redirected service dependency injection container [RedirectedDICont].

A special [DiCont] implementation allows to install redirectors for services. So if you request a type of service this object is not registered directly as a service in the container but an supplier object is registered which grants access to the service object. this is used for on demand loading of services.

service container fasade feature [RedirectedDICont].

The facade [Facade] composes the [LocalDICont], [VirtualDICont] and [RedirectedDICont] making it transparent to the client wether the service her requests is a local, virtual or redirected service.

[CmdExecCalc], [CmdAvailCalc], [CmdErrCalc]

[todo]

Property-Object feature [Prop], [PropObj]

The framework supplies a generic property which can be configured to implement various property strategies. VArious properties can be arranged to a property object. The framework can connect to any property so no special base class is required to use for objects can be bound to the framework. This feature is required for the [OrmAdapter]

Property's object model [PropOM]

Properties can contain objects of other [PropObj] objects. The framework supports managing such [PropOM] object models.

Propertiys dynamic implementation feature [PropDyn]

The property implementations can run in dynamically allocated property objects.

propertys code generation feature [PropGen]

All code for properties can be generated to replace dynamically [PropDyn] objects.

Property's buffer feature: [PropBuf]

A property can be configured to use a buffer.

Property's service feature: [ServicePropBuf]

A [PropBuf] can be connected to a service. The framework will then set the [PropBuf] to a service received from a [DICont].

Property's r/w feature: [PropRead] [PropWrite]

A Property can be configured to supply read and/or write operations.

Property's change notification feature. [PropObserve]

The property can be configured to generate code for change notification which includes code to adapt the Microsoft Windows Presentation foundation observer implemenation. (System.ComponentModel.INotifyPropertyChanged). This feature is available for [PropR] and [PropW] properties.

Property's lazy load feature: [PropLazyLoad]

The [Prop] can be configured to implement a lazy load strategy where a user defined calculation routine [PropInternalCalc] can be connected. The [PropInternalCalc] is called whenever a client requests the value of a property whichs buffer is set to 'not loaded'. [PropBufNotLoaded], [PropBufLoaded]

Property's auto-refresh feature: [PropRefresh]

The framework implements a input-value-dependency-recorder [IVDR]. The recorder is activated whenever the [PropRead] interceptor catches such events.

There are following conditions:

  • The property was called from an external client (for example a graphical user interface connected to a view-model) In this case the [IVDR] will record nothing.
  • The property was called from a [PropInternalCalc] routine In this case the [IVDR] will record a property to use an input value.

Whenever a recorded input value is changed using [PropOBserve] the calculated properties buffer is reset to [PropBufNotLoaded] Afterward a change-event is sent via [PropObserve]. If a client is observing the property it will request the property value which again causes calling the [PropInternalCalc] routine to recalculate the property value.

Propertiys user calculation routine [PropUDCalc]

By default the [PropInternalCalc] is connected to a user defined calculation routine used to calculate values for properties. For example a [PropUDCalc] can be implement to calculate the total amount of a bill.

Properties default value ffeature [PropDefCalc]

Properties can be configured to use to use a routine for calculating default values. The [PropDefCalc] routine is called from [PropInternalCalc] if a domain object was newly created on the user interface. For example a [PropDefCalc] can implement a number generator to supply a value for a new customer.

Properties new declaration feature [PropNewCalc]

Properties can be configured always to contain a valid object avoiding Null-reference exceptions. This feature comes close to the 'New' declaration in vb6. (See the difference to the new-declaration in vb.net: In vb.net a object will not be re-created after it was set to nothing. The difference to the vb-language feautre is that the user can implement a [PropUDNewCalc] method for user defined creating objects.

Propertie's inheritance feature [PropInherit]

Properties can be automatically inherited from lower level objects. For example in a typical application looking at [PropObj] objects you have at least model layer and a view-model layer. [MVVM] In a typicall enterprise application you have an additional [ORMLayer]. Now the framework can inherit properties to generate code for your view model to read values from the model layer which again reads them from the [ORM]-layer. Doing so you get an application which provides a user interface to edit, load and save data from/to a relational database. For this you do not have to write code to redifne properties in the view-model or in the model.

Properties validation feature [PropValCalc]

Propertys can be configured to call a user defined property value validation rule. [PropValCalc] This validation rule is called by the framework in various cases. For example it is called before a property value is written. However, depending on the client some values don't have to be checked. Consider a graphical user interface where a user can select values from a predefined list. [PreDefList] In this case the validation rule for the value needs to be included in the list is not required to be executed. Now consider a data import from another system. In this case you should run all available validation rules to ensure the data imported will not cause your system or your business-workflow to be corrupted. Similar cases apply to date values which can/must contain or not contain various details. For example a date/time must may or must not contain a time but (only) a date. If you use Date/Time gui editors friend to the framework these checks are not necessarry. More complex and more expensive checks will occur when looking at business objects like an order, a shipping or things like that.

Propertys predefined list feature [PreDefList]

A special validation rule [PropValidate] exists to check for predefined values. However, these lists can be automatically mapped to the user interface.

Propertys validation rule forwarding

(todo)

operation abstraction [OP]

There exists an abstraction layer for all calculation routines ([PropInternCalc], [PropUDCalc], [PropNewCalc], [PropValCalc] (...)) This abstraction layer includes also command routines [CmdExecCalc], [CmdAvailCalc], [CmdErrCalc].

Asynchronous [OP] feature.

This whole section is proprietary. Especially problems arising from combining various [AsyncMirror]-Modes must be identified. The feature matrix may not include all [AsyncMirror]-Modes described herein.

any [OP] operation can be declared to run asynchronously. [AsyncOp] In this case a property-client will trigger the process in the client-thread [ClientThread] when it invokes an [OP] on the supplier object. [AsyncSupObj] The framework will open up a thread-context for a background-worker [BwThread] in which the [Op] is executed.

Have a look at the difference between Backgroundworker oriented Multithreaded programme [BwMultiThreading] [MicrosoftBWPhiliosphy] and message-oriented//state-based multithreaded programming [MsgMultiThreading]. The framework supports a combinatation of both paradigmas. MsgMultiThreading is primarly used in [ProgressAsyncPropMirror] where it is implemented by [BwMultiThreading] However to implement [InstructionAsyncPropMirror] a [message queue] has to be implemented.

Before the [BWThread] context is opened various mirror objects will be created. Each mirror object in the [BWThread] represents a mirrorred object from the client thread. [MirrorObj] [MirroredObj] This mirror objects will be passed to the [BWThread] context so the [OP] executed asynchronously can use them. There is no on demand requesting mirrored objects by the [BWThread] from the [ClientThread] planned for now as it is not required in the concept, however, this would require the Framework implementation to use [MsgMultiThreading]

Async-mirroring of Services [DIservice]

The [BWThread] context contains mirrored representations of any service used by the calculation routine. [IVDR], [ServicePropBuf] To support this operation, services must implement the ICreateAsyncServiceMirror interface.

The standard use case for this the service which manages the [OrmObjContext]. The ICreateAsyncServiceMirror will need to clone the object and copy the connection string. [DbConString] This allows to open new ORM-Object-Context [OrmObjContext] in the [BWThread].

Async mirroring of [PropObj] objects. [PropAsyncMirror]

First there will be a [clone] of the [AsyncSupObj] which will be sent to the [BWThread] for execution.

There are serveral strategies a [Prop] can be mirrored:

  • No-Prop-Mirror

    In this case it is not possible to read or write an value from this property in the [BWThread].

    recalculated asnyc property mirror [RecalcAsyncPropMirror]

    In this case the properties in the [BWThread] will remain in [PropBufNotLoaded] state causing a [PropInternCalc] in the [BWThread]. This may load values from the [Db] which is quite critical in order you may get inconsistent states. It has to be verified if [RecalcPropMirror] is implemented.

    If this mode is exclusive and not combined with [ProgressAsyncPropMirror] property values can only be read in the [BWContext].

  • copy-loaded-async prop mirror [CopyLoadedAsyncPropMirror]

    In this case property values used by the calculation routine will be calculated in the [ClientThread] and transported to the [BWThread]. There may be conditions in the [PropInternCalc] routine which in various cases requires different input values. We need to know all input values to be copied to the [BwThread] context. Either the depending properties may be manually defined or a learning routine may use the [IVDR] executed within a testcase to learn all properties need to be copied to the [BWThread].

    However, in this mode only properties with [PropBufLoaded] state are copied. Other propertie's [PropInternCalc] are assumed to calculate the same value [PropInternCalc] or a value that is adequate in a asynchronous process.

    If this mode is exclusive and not combined with [ProgressAsyncPropMirror] property values can only be read in the [BWContext].

  • client-loaded async prop mirrior [CopyForceClientCalcAsyncPropMirror]

    This mode is similar to [CopyLoadedAsyncPropMirror] with the only difference, that [PropBufNotLoaded] values are loaded in the [ClientThread]. This is required for values calculated depending on input values from a view model. However, also this can be learned from [IVDR] executed from within a testcase.

    If this mode is exclusive and not combined with [ProgressAsyncPropMirror] property values can only be read in the [BWContext].

  • progress-asnyc-prop-mirror [ProgressAsyncPropMirror]

    In this mode property progress-values [ProgressVal] can be written in the [BWContext]. The new value effects the [PropBuf] of the [MirrorObj] which may cause recalc of other properties [PropRefresh] all running in the [BWThread]. The new value is also sent to the [ClientThread] where it will effect the [PropBuf] state of the [MirroredObj]. Analog [PropRefresh] sequences may be triggered in the [ClientThread].

    So writting a [ProgressVal] in the [BwThread] will first effect the state of the [MirrorObj] and (a little later) the state of the [MirroredObj]. [MirrorState], [MirroredState]. [AsyncStateInconsistent] can occur during these operations.

  • Instruction-async-prop-mirror [InstructionAsyncPropMirror]

    In this mode to the [MirroredState] will be transmitted to the [BWThread]. (reverse to the [ProgressAsyncPropMirror]. Again the [AsyncStateInconsistent] may occur.

[AsyncStateInconsistent]

In [ProgressAsyncPropMirror] there is a special case where a user has modified the [MirroredState] while the [ProgressVal] was calculated. This may cause the writting the [ProgressVal] to the [MirrorObj] to succedd but writting the [ProgressVal] to the [MirroredObj] will fail. A similar case causes this state during [InstructionAsyncPropMirror] operations.

[AsyncStateInconsistentBwAbort]

In case of [AsyncStateInconsistent] the [BWThread] has to be aborted and no more [ProgressVals] can be accepted to effect the [PropBuf] of the [MirroredObj].

[AsyncStateInconsistentSavePrevention]

In [AsyncStateInconsistent] optionally the [MirroredObj] can be set to a inconsistent state [MirroredObjInconsistent] where it is not allowed to be saved or modify persistent objects. However, if persistent objects have allready been modified they must be optionally prevented from beeing saved until the [BWTherad] terminated successfully. Defining these rules are very application specific and it is error prone for application developers to do this.

[AsyncStateInconsistentNoPersistModifyPrevention]

The framework may support to detect cases where [ProgressVal] effect the persistent state of an object and disallow this. This will avoid problems arising from missing [AsyncStateInconsistentSavePrevention]. This will cause the [AsyncStateInconsistentBwAbort] to take effect.

Bi-directional Active object support [ActObj], [BiDiActObj]

Active objects require a state machine in order to work properly. These state machines may be composed using the folliwing events:

  • Property [Prop].AsyncReadIsPending

    this property designates wether the property value is currently asyncronously laoded. [AsyncOp][PropInternCalc]

  • Property [Prop].AsyncWriteIsPending

    this property designates wehter the property value is currently transmitted to the other thread using [

  • [todo] events

Active-object networks

A simple case is an active object star-network [NetworkTopologies]. When nodes of the star start to open up [BiDiActObj] communications in a mesh or fully connected network this is very hard to control at some point. When doing so problems like deadlooks and race conditions start to become error causes. Thus such a terminology is not recommended and should not be required in our system. Compare the [BwMultiThreading].

[OrmAdapter]

[Todo]

Literature

[DICont] Microsoft tutorial for dependency injection
[ORM] Wiki-article for object relational mapping
Some well described object-relational design patterns
[MVVM] blog article for how to use model-view-view-model architecture in microsoft presentation foundation guis
[OrmAdapter] Wiki Article for the adapter pattern
[Interceptor] Wiki article for the interceptor design pattern (Note we don't use it asynchrounously)
[Observer] Wiki article for the observer pattern
Description of the event keyword in visual basic
[LazyLoad] Wiki article for the lazy load pattern
[DbConString]Connection string examples
[OrmObjContext] The .NET DataContext class
[CLone]Wiki Article for the prototype pattern
[Db]Wiki Article for Microsoft SQL-Server
[BwMultiThreading] Microsoft article of how to use BackgroundWorker
[MsgMultiThreading]Some links for massively asynchronous, message based multithreading
[ActObj]Wiki Article for the Active-Object pattern
[NetwiorkToplogies]Wiki Article for network topologies
[Facade]Wiki Article for the facade pattern

Montag, 29. März 2010

2010-03-29-Vb20xx-Bottlenecks and traps using Linq with expensive select-expressions

VersionDescription
2010-03-29 T15:51:00Corrected formula for number of calls to new.

Description:

Implement Lazy-Load pattern for IEnumerator.Item[Get].

Problem:

If you are a linq-beginner there is something you should really be aware of before using it. Otherwise some day you may wonder about strange bugs or bad performance of your linq application.

Starting with linq some months ago I meanwhile like it very much and went deeply in using Linq-querys for various use cases. I used the select expression also to instantiate objects as shown in the below code snippet. Doing so i walked in a trap because i was not aware, that the select expression is evaluated each time the object set is enumerated. Also complex queries may be evaluated very often which increases runtime costs when the result tree is not copied.

Consider the following Vb.Net code:

 Dim aCount As Integer = (From aNum In New Integer() {1,2,3} Select New Object).Count

This query seems ok, but the problem is, that new objects are instantiated each time the list is iterated and even if one uses the Count-extension-method. This results in a number of calls to new of n * c + n * i where n is the number of items in the list, c is the number of requests to the count method and i is the number of iterations. The required number of calls to new is more less equal to n.

I now use following extension method to solve this problem and get the desired number of n calls to new:


 Module MyExtensions
  <System.Runtime.CompilerServices.Extension()>_
  Friend Function EvaluateItems(Of T)(ByVal aItems As IEnumerable(Of Func(Of T))) As IEnumerable(Of T)
   Dim aArray As T()
   Dim aCount As Integer = aItems.Count
   ReDim aArray(aCount - 1)
   Dim aIndex As Integer
   Dim aItem As Func(Of T)
   For Each aItem In aItems
    aArray(aIndex) = aItem()
    aIndex = aIndex + 1
    Next
   Return aArray
  End Function
 End Module

 Dim aQuery As IEnumerable(Of Func(Of Object)) = (From aNum In New Integer() {1,2,3} Select Function() New Object)  Dim aCount1 As Integer = aQuery.Count
 Dim aObjects As IEnumerable(Of Object) = aQuery.EvaluateItems
 Dim aCount2 As Integer = aObjects.Count

With the obove code only n constructors calls occur where n is the number of objects in the list.

However, i have one suggestions here.

Of course it is necessarry that the select expression is evaluated each time the item is requested. However, this does not apply if the list is only enumerated using IEnumerator.MoveNext without using IEnumerator.Item[Get]. The Interface design is suitable for implementing a lazy load here but (linq)-implementations of IEnumerable do not follow this.

I also wrote a extension method to (deep)-copy any IEnumerable tree for optimizing complex queries where updating is handled by the owner of the query result. The implementation quite tricky and not not so good so i don't post it here yet. Maybe Microsoft could provide a default extension method or a code snippet to do this.

Beside of this i'd like to suggest linq to implement a lazy load in IEnumerator.Item.Get to allow iteration without evaluating the select expression. For example this is done when counting items or when requesting an item at the end of the object set using ElementAt. For some use cases (for example implementing paging) this behaviour is required.

Solution:

1a. Implement lazy load in certain IEnumerator.Item[Get] implementations. (For example Linq)

Or

1b. provide extension method to create a ghost-list.

2. Provide a IEnumerable-Extension method which deep-copys items in an ienumerable (to an array) to avoid unneccesarry evaluations of the select expression.

TestCase:


 Class C
  Public Sub New()
   InstanceCount = InstanceCount + 1
  End Sub
  Public Shared InstanceCount As Integer
 End Class

 Module Test

  Function MyCount(ByVal a As IEnumerable) As Integer
   Dim aCount As Integer
   Dim aEnumerator As IEnumerator = a.GetEnumerator
   While aEnumerator.MoveNext
    aCount = aCount + 1
   End While
   Return aCount
  End Function

  Sub Test
   Debug.Assert(3 = MyCount((From aNum In New Integer() {1,2,3} Select New C).CreateGhostList)
   Dim aSuggestionImplemented As Boolean = True
   If aSuggestionImplemented Then
    ' This will fail with Vb.Net 2010
    Debug.Assert(0 = C.InstanceCount)
   Else
    ' In Vb.Net 2010 using IEnumerator.MoveNext evaluates the Select expression of a linq-query.
    Debug.Assert(3 = C.InstanceCount)
   End If
  End Sub

  End Module

Freitag, 5. März 2010

Language integration of well know Design-Patterns

Since the mid 70s or so design patterns have become a powerfull way of standardizing the static object model of a software application.

I manage that there seems to be less awareness or understanding that for certain patterns there exist language integrations.

For example since Microsoft Visual Basic 6 there exists the Keyword "Event". Using this single keyword you can define an observable object, and with another keyword (in vb.net it is 'Handles') you can define an Observer pattern in ~3 lines of code. Some years ago in c++ you may have written some hundred lines of code to do so.

Look at the Decorator pattern. This pattern in fundamental way does just the same thing which you can implement in Aspect oriented languages which gives you much more power than standard implementations of the pattern could provide.

Well, this whole thing is quite amazing. It boosts compactness of code to a quite high level. Compared to the code reduction you get generating Assembler code for a function or object this is quantum jump in the ongoing process of defining higher languages.

I hope that more language integrations for well known patterns will become popular and some day we'll have language-integration lists for various patterns.

The homogenity of languages goes on. Some years ago and nowadays industrial software projects may contain a dozens of proprietary interface definition languages and each step between languages or systems requires a lot of marshalling code which is not always generated. Think how many design patterns you use in one software project. May there be each or at least some design patterns implemented using a domain specific language or a special keyword? Well, using .NET Plattform you allready do it. Using Aspect J you allready do it.

I'm thinking of a list of language integrations of well known patterns but compared to the number of patterns there seem to exist not too much for now.

PatternLanguage integration
GOF-ObserverMicrosoft VisualBasic "Event" Keyword/other clr-syntaxes
GOF-DecoratorAspect oriented languages
GOF-StateUML-Statemachine/other statemachines
Reflection -Reflection-APIs of various languages (.NET/CLR, Java,c++ rtti ...)
-Dynamic languages (in restricted way)

Mittwoch, 24. Februar 2010

2010-02-24-Vb20xx-reflapi-Karl-Michael Beck To LW

Keywords

  • Type safe reflection api.
  • Inheriting from Generic-type-arguments

version: 2010-02-24T23:15

Hi L,
I would suggest to implement an extended type system for compiletime checked type safety of code generators and other code using reflection.

1. Problem: Reflection APi not type safe.

A language integrated code generator and code based on reflection may want to use a reflection-api that supports compile-time checks. Using reflection is not type safe. If you accept an type object there are very often constraints to type objects valid for specific use cases. These constraints can be checked at runtime but there is no compiletime check for it.

2. Problem: Inherit from generic-template-arguments

As in c++ a class can be inherited from template arguments users may want to inherit from generic type parameters in vb. As vb supports type constraints for generic type arguments working with base type members inherited from generic type arguments can be compile-time checked.

2. Solution: Provide a type safe reflection api.

' Begin Vb20xx
Class B
End Class
Class C
  Inherits B
End Class
Class Demo
  Sub S
   Dim ob As B = New C ' valid cast: C is kind of B
   Dim oc As C = New B ' compiler error: B is not kind of C
   Dim tc As Type = GetType(B)
   Dim tb As Type(Of B) = GetType(C) ' Valid cast: C is kind of B
   Dim tc As Type(Of C) = GetType(B) ' Compiler error: B is not kind of C
  End Sub
End Class
' End Vb20xx

2. Solution: Inherit from generic-type-arguments.

The mechanism needed to implement solution 1 has something todo with the ability to inherit from generic-type-arguments. This feature may also be public for the users. However, there must be some new layers for type-system implemented for the final type system requires to use this service.

' Begin Vb20xx
Class C
End Class
Class G(Of T As C)
  Inherits T ' inherits any member in C and any member in T.
  Sub New()
   Dim c As C = Me ' Valid cast: T is constrained to C.
  End Sub
End Class
' End Vb20xx

Note: A Problem arising here is, that each member in the generic type must be implicitely declared as shadows. But i guess, together with a homogenous naming system this case is quite strange.

2010-02-25-Vb20xx-multiinh-Karl-Michael Beck To LW

Keywords

  • Use InheritNoData to use Multiple inheritance with NoData-Inheritance mode.
  • Use MemberContext to extend classes in local scopes.
  • Use Identifier-Mapping when overriding members.
  • Use BadCast and GoodCast to separate casting-use-cases.

version: 2010-02-24T23:01

This article contains a suggestion for language extension which may be implemented in further versions of the microsoft visual basic programming language.

The article's homepage is http://karlchenscoderdasein.blogspot.com/2010/02/2010-02-24-vb20xx-karl-michael-beck-to.html

Dear Reader,

if you are a microsoft employee to categorice this content please read the solution first.
I allready have contact to vb-lead-spec but would like to use this platform to keep up your working process.
In the non-public area i have the email adress of the vb-lead-spec-employee in question.

Hi L.,

i'll come back later for your code-generator-language.
I think i have an good alternative for the code-generator-internal-type system you talked about.

For now i have another 4 issues which i think are very usefull:

1. Problem: Multiple inheritance

Using virtual inheritance may be very usefull but brings some very sophisticated rules with it, which may confuse developers and rise development costs. Refer to the c++ memory managment for multiple, virtual inheritance and the arising rules for usage of base-base-class constructor and default constructor.

This may be one reason not to support multiple inheritance in a given language like in vb.net.

For a good reason to use multiple inheritance refer to the problems in a visitor pattern arising in vb.net:

Refer to the visitor pattern introduced in Problem/solution 1-3.

In vb.net 2010 you have two alternatives:

1.1. Define a Visitor Base class

1.1.1. Pro: You may implement empty visit-methods in the base class so specific visitors may only override the visit-methods they need.

1.1.2. Contra: you can not implement a visitor in a class which allready has another base class.You need to write extra delegation code.

1.2. Define a visitor-interface:

1.1.1. Pro: You may implement the interface in any class which already has a base class.

1.1.2. Contra: You need to implement all visit-methods although if you don't need them in a specific visitor

I would like to introduce a language specification which alows to eliminate the above cons and implements a safer way of multiple inheritance.

2. Problem: Lots of Dependencies

Refer to the visitor pattern introduced in Problem/solution 1-3.

The visitor-pattern in a very fundamental way shows how you get unwanted dependencies in classes. Often the responsibilites in the visit-methods-arguments have totally nothing to do with the responsibility of the class which needs to declare the accept methods. Actually the class declaring the accept method may be a generic container-class which with the visitor pattern has a dependency to types which may be generic type-arguments. But users accept this unneccesary dependency because they are avoding bad-casts from the base class to the child class. (By using the visitor-pattern you can implement get the same results as with a bad-cast but you are not loosing compiler checks)

I would like to introduce a language specification way which allows to implement the pattern without producing such dependencies.

3. Problem: Base-Method Mapping

I have some patterns which produce naming-conflicts when overriding methods. They may also arise in the solution of Problem 2.

4. PRoblem: Bad-Cast and Good-Cast is not separated with CType, DirectCast.

Currently there is only CType or DirectCast. They are not suitable to distinguish following cases:

1. The users does a good-cast fro a child class to a base class or to the same class. This is only done to clarify code.

2. The user does a bad-cast from the base class to the child class.

In vb2010 users will use directcast or CType for both cases.

==============================================================================================================================

Dear Reader,

if you are a microsoft employee to categorice this content you may forward it to L.W. (l.w@microsoft.com)

Solutions:

Solution 1: Support 2 inheritance modes: data-inheritance and no-data-inheritance.

Refer to the visitor pattern introduced in Problem/solution 1-3.

Support declaration of no-data-classes. Inheritance can use:

0..1 Data-Classes
0..* NoData-classes

' Begin Vb20XX:
Public DataClass CMyDataBaseClass1
End Class
Public DataClass CMyDataBaseClass2
End Class
Public NoDataClass CMyNoDataClass1
End Class
Public NoDataClass CMyNoDataClass2
 Private m as Integer ' compiler-error: no data allowed in no-data-classes
End Class
Public DataClass CMyChildClass
 InheritsData CMyDataBaseClass1
 InheritsData CMyDataBaseClass2 ' Compiler error: only 1 data base class allowed.
 InheritsNoData CMyNoDataClass1
 InheritsNoData CMyNoDataClass2
 InheritsNoData CMyDataBaseClass2 ' Compiler error: data class can not be used for nodata class inheritance.
End Class
' End Vb20XX:

Applying this language specifications to the visitor pattern allows to define visit-methods in a no-data-base-class which can be used as baseclass anywhere.

Consider what the user will do if he needs to access data: HE will declare mustoverride Properties in the no-dataclasses which he will implement in child classes. Like this the user is forced to explicitely declare how memory managment is done and he has more oppertunities than in c++. Refer to solution 3 for this issue.

Following this pattern naming conflicts can arise which i would like to solve in Solution 3.

==============================================================================================================================

Solution 2. Support object-context specific extensions for classes:

Refer to the visitor pattern introduced in Problem/solution 1-3.

Consider implementations of the Visitor pattern. You will notice that you may have a lot of dependency in the class which provides the base methods for the Accept routine.

I could imagine a mechanism that solves this problem.

I would like to define members for a class which only are visible in a specific "member-context". Such a membercontext is very similar to a namespace. So it may result in each membercontext having an own v-table and an own type-descriptor.

I would like to dynamically attach these members to allready compiled clr-code.

Imagine:

' Begin Vb20XX:
MemberContext MC1
  Namespace N1
   Class Ag
    ' this class will be extended with a visitor-pattern in another member-context
    ' you can not access/see the visitor pattern here.
   End Class
   Class B
    Inherits A
   End Class
  End Namespace
End MemberContext

' this member context implements the visitor pattern (maybe in another assembly)
MemberContext MC2
  Namespace N2 ' this namespace matches to the above namespace in MC1
    Friend Partial Class A
      Friend Overridable Sub Accept(ByVal aVisitor As CVisitor) ' member only valid in MC2.
        Throw New NotImplementedException("Method should be overridden.") ' MustOverride seems not to be applicable here.
      End Sub
    End Class
  End Namespace
   Friend Partial Class B
    Friend Overrides Sub Accept(ByVAl aVisitor As CVisitor)
     aVisitor.VisitB(Me)
    End Sub
   End Class
   Friend Class C ' This class only exists in MC2
    Inherits A
    Friend Overrides Sub Accept(ByVAl aVisitor As CVisitor)
     aVisitor.VisitC(Me)
    End Sub
   End Class
  Friend NoDataClass CVisitor
   Public Overridable Sub VisitB(ByVAl b As B)
   End Sub
   Public Overridable Sub VisitC(ByVAl c As C)
   End Sub
  End Class
  Partial Class A
   Friend Mustoverride Sub Accept(ByVAl aVisitor As CVisitor)
  End Class
End MemberContext
' End Vb20XX:

Using this language specifiication any user may define additional dependencies which only apply in his member context. Other users can not see/access the members defined in a member context unless they are declared public rather than friend.

==============================================================================================================================

Solution 3. OVerride-Name-Mapping

I would like to map implementations of base-class members similar to the interface-implemenation mapping supported in vb 2008

' Begin Vb2010:
  Interface I
    Sub F()
  End Interface
  Class C
   Implements I
   Protected Sub FImpl() Implements I.F
   End SUb
  End Class
' End Vb2010:
' Begin Vb20XX:
  Class B
   Public MustOverride Sub F()
  End Class
  Class C
    Inherits B
    Private Sub FOverride() As CBaseType OVerrides MyBaseClass.F
    End Sub
    Public Shadows Sub F() As CChildType
    End Sub
' End Vb20XX:

Refer to the no-data-inheritance in solution 2:

Several No-Data-Base-Classes may define MustOverride-data-accessors which have the same name but in the child class implementing the data the abstraction level is lowered and the identifiers may become more concrete. A use case of this pattern is described in solution 1.

For example:

' Begin Vb20XX:
Public NoDataClass Nd1
  Public MustOverride ReadOnly Property O As Object
End Class
Public NoDataClass Nd2
  Public MustOverride ReadOnly Property O As Object
End Class
Public DataClass D1
  Inherits NoData Nd1
  Inherits NoData Nd2
  Public Mustinherit ReadOnly Property O1 As OBject Overrides Nd1.O
  Public Mustinherit ReadOnly Property O2 As OBject Overrides Nd2.O
End Class
' compiler error when referencing D1.O: member is not accessable: the identifier is ambiguous.
' End Vb20XX:

4. BadCast/Good Cast keywords

I'd like to introduce a language specification which defines keywords to clearly separate cast-use-cases.

' Begin Vb20XX:
Class B
End Class
Class C
  Inherits B
End Class

Class Test
  Shared Sub Execute()
   Call GoodCast(New C, B)
   Call GoodCast(New B, C) ' Compiler error
   Call BadCast(New C, B) ' compiler error
   Call BadCast(New B, C)
  End Sub
End Class
' End Vb20XX