Monday, February 28, 2005
Passing Data I/O from data Access Tier
there are 4 ways to pass data I/O from data access layer .
1- Scalar Values : In this case, the caller does not need to know the structure of the entity. it is the most efficient input because only the necessary data is passed . The main disadvantage of this approach is that changes in the underlying data structure may require a corresponding change in the method signature . If the method signature needs to be altered to take account of a new field for example , all uses of that method must be tracked down and changed.
2- XML Strings : passing data by using a single data structure .By gathering all of the data for a business entity , exchanges between applications become much more efficient because data is not broken into multiple discrete units. another advantage will be that XML can be digested by almost every application . The disadvantage of this technique is : tagged data introduces reduntant information .
3- Datasets :
a- has optimistic concurrency issues built in on the contrary to ADO objects .
b- can hold collections of data corresponding to individual business entities (implemented as table rows) and are well-adapted to hierarchical data.
c- When a method accepts a DataSet as an input type, changes to the DataSet schema do not require changes to the method signature.
d- incorporate the advantages of XML formats because they can be quickly serialized and deserialized.
Disadvatages : a- big object in memory resulting in high marshaling costs .
4- Custom Entity Components : are implemented as classes or structs(which has better performance . it is a more flexible dynamic way than datasets . they typically represents the underlying business entities (e.g Employee class representing an Employee ). they can also be serialized as XML . they can be created to avoid the high marshaling costs of datasets while gaining the adv of strong typing .
Disadvantages :
a- representing these entities in Collection will need creating string typed collection or use the ArrayList , which is not the case in Datasets .
b- the custom collections or the builtin collections in .NET doesnt represent the heirarchy , in contract to datasets relations and also provide filtering and sorting .
c- binding to controls . they must implement ICollection to be able to be bounded .
Summary :
I- DataSets are recommended if the application is primarily workingwith large collections of items and needs standard sorting, filtering,and searching capabilities. This is especially true if the data needs toincorporate complex or hierarchical relationships.
II- If the application mainly works with instance data (for example, a single Customer or Project object), custom business entities will normally be the better choice. There is no need for the overhead of DataSets when only one row of data is sufficient for most purposes.
III- In many cases, the time and effort of creating custom business entities will not be worth
Wednesday, February 23, 2005
Passing a value Type ByVal Tricky Question ?
this is a small tricky question : ( Very IMP )
what is the Console.WriteLine going to print ?
public class Reference public struct Value
{ {
public int i; public int i; //Not Private
public int Prop public int Prop
{ {
get {return i;} get {return i;}
set {i = value;} set {i = value;}
} }
} }
classExample
{
private Reference_r; // Reference type
private Value_v; // Value type
public Example()
{
_r = new Reference();
_v = new Value();
}
public Reference RefProp
{
get {return _r;}
set {_r = value;}
}
public Value ValueProp
{
get {return _v;}
set {_v = value; }
}
}
class Program
{
static void Main(string[] args)
{
Example e = new Example();
e.ValueProp.i = 4;
Console.WriteLine(e.ValueProp.i); // what is going to be printed after this line ?
}
}
take care of the line : e.ValueProp.i = 4;
let's divide this line , e.ValueProp is going to return an instance of the Value Struct , then we go ahead and change the "i" field on this struct
so first part is getting the Value instance from the ValueProp :
Value v1 = e.ValueProp; //is V1 is going to take a copy of the returned Value instance or going to reference this instance ?
// of course it is going to take a copy . coz this is a value type byVal assignment
SO
v1.i = 4; //is going to change the "i" field on the copied Instance not the original . so the Console.WriteLine should Print 0
// but the Compiler detects this issue and throw a compile error .
Tuesday, February 22, 2005
Why Do We have Different exception Classes ?
i still get the same question frequently . why do we have more than 1 exception class ?
isnt it enough to write code like this :
try {
// protected Code}
catch (Exception ex)
{ // switch (ex) and handle each exception separately }
the exception class will catch all kind of exceptions . and we can internally handle each exception separately .
no , this is not enough , why ?
let's take this sample
try {System.IO.File.Delete("z:\filenotfound.txt");}
catch (exception ex) { //what can we do here if we need to know the name of the file which is not found ?}
so there must be some "Data" about the kind of exception taking place , in our case the name of the file .so that's why we have FileNotFoundException . so it is much more convinient to write something like this :
try {System.IO.File.Delete("z:\filenotfound.txt");}
catch (FileNotFoundException ex) { Console.Writeline(ex.FileName);}
another example will be the ArgumentOutOfRangeException : we need to know the original value of the argument which is out of range .
try {//cause some argument out of range error;}
catch (ArgumentOutOfRangeException ex) { Console.Writeline(ex.ActualValue);}
VS 2005 :
so what is new in 2005 . in VS 2005 we have all the exception classes having a new property which is : Data , that contains all the information available about this error . it looks like the event model of .NET where Microsoft encapsulates all the information about any event in the second parameter of the event "EventArgs e". so now we have "Exception.Data"
Wednesday, February 16, 2005
Why do we have 2 Comaprison Operators in VB ?
the 2 comparison operators i am talking about here are : "Is" and "="
actually , the existence of both of them returns to the old VB6 . coz for old classes we used to have 3 property accessors : "Let , get and set " and the old mistake "default properties "
so we can say simply in VB6 :
Label1 = "User Name : " which means Let Label1 = "User Name : "
and we can also say
Label1 = new Label() which means Set Label1 = new label()
so in the past if we say :
if label1 = "User name" then 'do something this is a using of the opreator "="
but if we say if Label1 = label2 then 'do something this invokes the "Is" operator .
we no more have "set" in VB.NET , so some people think "Is" should have been removed from the language as well and have only 1 comparison .
but it is due to simplicity and more readability (from my point of view) that they still keep the "Is" so we still have reference comaprison as well as value comparison or else we are going to write it as the other languages Object.ReferenceEquals(a,b) . so using "Is" is much more readable and cleaner ..
Tuesday, February 15, 2005
Another Hall Of Shame
Constructor for ArgumentNullException
public ArgumentNullException( string paramName, string message)
Constructor for ArgumentException
public ArgumentException( string message, string paramName)
ArgumentNullException does not follow the constructor pattern
Monday, February 14, 2005
Installing the msn Toolbar beta on windows 2003 Server
msiexec
Sunday, February 13, 2005
unboxing in VB is different than C#
another point for VB against C#
let's do this example :
in C# :
int i = 7;
object myObj;
myObj = (object)i; //boxing
long j = (long)o; //InvalidCastException
the CLR will only let you convert it back to Integer
in VB :
Dim i As Integer = 4
Dim myobj As Object
myobj = i 'boxing
Dim j As Long = CType(myobj, Long) 'unboxing works fine
'However
Dim k as long = DirectCast (myobj, Long) 'Generates an error coz DirectCast Bypass VB Helper Funs
How is Works :
To make this work, the compiler emits a conversion from Object as a call to a helper function. The helper function takes the Object, looks at the type of the value contained in it and then does the appropriate conversion to the target type. this means an extra step . it might be an extra step in the wrong direction in case i know the returned type , so i will only lose some performace.
so the Rule is : if i know the result TYPE i would use DirectCast which bypasses the VB helper functions , and i get some performance gain .
as you see , the Default is the helper funs , so the language by default (cint , clong , ctype , etc ... ) can unbox to any type unless you need to switch off this nice feature using DirectCast .
this means that , it is not possible to express all VB language in IL . there are some helper functions like Late Binding ( i will take about this later in coming post) which is not found in IL . that's why we need Microsoft.visualbasic.dll in all the VB projects and we cannot remove that reference .
Saturday, February 12, 2005
at Last i found Why don't I get an exception when I divide by zero in VB.NET?
of course not everyone will like this explanation coz it is deep technical , but this is the Man Behind VB.NET reply to that question
While talking about exception handling, Roy ran up against a change in behavior from VB6 to VB.NET. In VB6, if you evaluate the expression "x = x / 0", you'll immediately get a divide by zero exception. In VB.NET, if you evaluate the same expression, no exception is thrown. Instead the value of x is now NaN, also known as "Not a Number." In reality, you could get this behavior in VB6 as well - on the Compile tab of the project properties, there's an "Advanced Optimizations" button that includes an option "Remove Floating Point Error Checks." If you check that and make an exe (it doesn't affect F5 in the IDE), then the assignment will work and x will contain the value NaN.
The reason for all this is that floating point numbers (as defined by the IEEE) support a number of special values that aren't usually surfaced to VB programmers. In addition to NaN, a floating point variable can also contain the values positive and negative infinity. Not being a numerical expert, I won't even pretend to explain what these values are for or why the IEEE felt they were important to include as part of the definition of floating point numbers. The bottom line is that they are there. By default in VB6, though, we inserted X86 instructions that checked for the various non-numerical states and would throw an exception if you encountered one. In VB.NET, however, things were complicated by the way that the CLR IL was designed, namely the fact that it doesn't support a really efficient way to check for non-numerical results. In VB 2002, we tried simulating the VB6 behavior by emitting CKFINITE opcodes after each floating point operation, but this absolutely tanked all floating point performance. So we ended up dropping the VB6 behavior, and now floating point division by zero will result in NaN instead of an exception.
A related issue is that most processors' FPU registers can handle floating point numbers with a higher precision than can be stored in the standard .NET Double datatype. As a result, depending on how the CLR JIT compiler enregisters variables and temporary values, it's possible that floating point operations (including comparisons) can be done at differing levels of precision. For example, the following code could print "False" instead of "True":
Dim d1, d2 As Double
d1 = Atn(-1)
d2 = Atn(-1)
If d1 = d2 Then
Console.WriteLine("True")
Else
Console.WriteLine("False")
End If
That's because one of the variables could be left in a FPU register while the other variable is actually stored back on the stack. When you compare the two values, they aren't equal because one of the values was truncated (so it could be stored on the stack) and the other value wasn't. By default, VB6 suppressed this behavior by emitting X86 code to truncate values that were at higher precisions. (You can turn this off on the advanced optimizations page, too, under the option "Allow Unrounded Floating Point Operations.") But the CLR equivalent - inserting CONV.R8 opcodes everywhere a higher precision value might be used - had similar performance problems to the NaN checks.
As a result, VB.NET floating point operations are much "closer to the metal," which is either a good thing or a bad thing depending on your perspective. You definitely have to be a little more aware of what you're doing when dealing with floating point numbers...
In a response to my previous entry, Cory asks:
...how would you solve the comparison of two values if one is still on the stack and the other has been [stored in a register]? In other words, what would be the proper way to handle this type of situation (work around, etc.)?
A good question, and one that I should have addressed. You can get the compiler to insert explicit CONV.R8 opcodes by using the CDbl() conversion operator. So the code example would look like:
Dim d1, d2 As Double
d1 = Atn(-1)
d2 = Atn(-1)
If CDbl(d1) = CDbl(d2) Then
Console.WriteLine("True")
Else
Console.WriteLine("False")
End If
If you look at the code this compiles to, you should see CONV.R8 opcodes after each local is loaded, and that should force the values to both be truncated
Can We turn OFF the background compilation for VB
no we cannot do that . there were many requests for that in VB 2002 coz huge projects were slow , but this was solved in 2003 . the main reason why MS cannot give a switch to turn off this feature is :
The information provided by background compilation drives Intellisense, it enables the WinForms designer (as well as all other designers), it fills the dropdowns at the top of the window, it drives the object browser, it enables go to definition, etc, etc, etc. Essentially, without background compilation, the IDE becomes Notepad.exe with syntax coloring. (Coloring, interestingly enough, does not require background compilation because it's entirely based off the lexical grammar of the language and requires no further knowledge of the code.)
another Point for VB against C#
this is another VB vs C# thing :
some people say : Given VBA's long history with Office, one might expect VB .NET to be the primary language among .NET developers using Office as a platform. But I've seen a lot of evidence that C# usage of Visual Studio Tools for Office (aka VSTO) is high.
so programming against Office is one of those places where VB has got it over C# hands-down
1- C# can’t bind to Word’s Close event and VB can
in C# we cannot have :
private void ThisDocument_CloseEvent()
{
}
while in VB we have :
Private Sub ThisDocument_CloseEvent() Handles Me.CloseEvent
End Sub
2- printing a word document , since VB Supports named Arguments , :
in VB : Doc.PrintOut(Copies := 2, Collate := true)
in C# :
object copies = 2;
object collate = true;
Doc.PrintOut(ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref copies,
ref missing, ref missing, ref missing, ref collate,
ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing);