I was wondering whether do I need to have separate namespaces for each layer, such as MyComponent.DAL, MyComponent.BO, MyComponent.Service. What are the pros and cons of having/not having separate namespaces?
I see two approaches here.
Approach #1
Separate DLLs for each component containing layers in separate namespaces (UI, Service, BO, DAL) as follows,
Component1.dll with Component_1.DAL, Component_1.BO, Component_1.Service and Component_2.UI
Component2.dll with Component_2.DAL, Component_2.BO, Component_2.Service and Component_2.UI
...
...
...
Component_N.dll with Component_N.DAL, Component_N.BO, Component_N.Service and Component_N.UI
Approach #2
Separate DLLs for each layer containing all components as follows,
UI.dll
Service.dll
BO.dll
DAL.dll
In Approach #1, addition of components is easy without affecting other modules. But in Approach #2, recompilation of whole system is needed (UI.dll, Service.dll, BO.dll, DAL.dll). On the other hand, Approach #2 facilitates easy replacement of layers.
Architect's Advice
Components are usually self contained and are deployed at only one layer, say, business logic or data access or user interface, where as modules cut across all layers.
With Approach #1,
You would be able to have module specific DLLs with need of recompiling and distribution limited to that assembly only. This will improve management and distribution and is good if you are planning to provide this as one unit of functionality to end user/client. In this model, you can scale out by deploying such components on multiple machines and is usually called vertical partitioning of application. You can easily replace one module with another or add new module as new set of functionality.
In this approach if you have to modify cross cutting concerns like change in UI framework or UI standards or introducing new UI pattern or providing centralized business rules, caching, exception, logging/tracing, transaction management, data access functionality then you will have to change each and every module/component specific dlls to incorporate this change. Additionally you will have to manage the dlls of cross cutting concerns in each and every module increasing the overall module size and you will lose on ensuring flexibility and consistency of standards for cross cutting concerns across modules.
This approach is good if you are building a small size product which you want to distribute to clients who can run it by installing locally and doesn’t need high amount of resources like CPU/memory/databases to run and you can define self contained standards for all cross cutting concerns and cross cutting concerns changes from modules to modules or clients to clients where you provide this as tailored functionality. Has limitation on scaling Up. UI, business, data access in total can consume lots of memory on the machine. Scaling out will not be possible as all are tightly coupled into one assembly.
Approach #2 has consequence of recompiling but it helps you to,
1. Maintain consistent standards and provides high flexibility for cross cutting concerns across all your layers.
2. Recommended in scenario where modules (components) are usually known upfront and incremental addition of modules is not expected frequently as against modification of functionality within module.
3. You can easily scale up and scale out by tiering approach as against approach #1.
Tuesday, September 8, 2009
Friday, July 3, 2009
Creating SQL Job using T-SQL Statements
The following shows how to create and add scheduled SQL jobs in MS SQL Server.
EXECUTE msdb.dbo.sp_add_job
@job_name = 'Database Backup',
@enabled = 1,
@owner_login_name = 'sa'
EXECUTE msdb.dbo.sp_add_schedule
@schedule_name = 'Daily database backup',
@enabled = 1,
@freq_type = 4, -- daily
@freq_interval = 1, -- daily
@active_start_time = '180000'
EXECUTE msdb.dbo.sp_attach_schedule
@job_name = 'Database Backup',
@schedule_name = 'Daily database backup'
EXECUTE msdb.dbo.sp_add_jobserver
@job_name = 'Database Backup',
@server_name = 'ServerName'
EXECUTE msdb.dbo.sp_add_jobstep
@job_name = 'Database Backup',
@step_name = 'Backup database on daily basis',
@subsystem = 'TSQL',
@command = 'BACKUP DATABASE TestDatabase TO DISK = ''C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\BACKUP\TestDatabase.bak''
EXECUTE msdb.dbo.sp_add_job
@job_name = 'Database Backup',
@enabled = 1,
@owner_login_name = 'sa'
EXECUTE msdb.dbo.sp_add_schedule
@schedule_name = 'Daily database backup',
@enabled = 1,
@freq_type = 4, -- daily
@freq_interval = 1, -- daily
@active_start_time = '180000'
EXECUTE msdb.dbo.sp_attach_schedule
@job_name = 'Database Backup',
@schedule_name = 'Daily database backup'
EXECUTE msdb.dbo.sp_add_jobserver
@job_name = 'Database Backup',
@server_name = 'ServerName'
EXECUTE msdb.dbo.sp_add_jobstep
@job_name = 'Database Backup',
@step_name = 'Backup database on daily basis',
@subsystem = 'TSQL',
@command = 'BACKUP DATABASE TestDatabase TO DISK = ''C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\BACKUP\TestDatabase.bak''
Thursday, July 2, 2009
Retrieving Client Browser's Culture in ASP.NET
I fall in a couple of situations where I needed to get the client’s culture from the server side in an ASP.NET application. I googled this and found only client side solutions, but I knew there was some way to get this information because the ASP.NET framework supports client based culture (through the UI Culture = "Auto" in the page attributes and the globalization section in the web.config). The only way I thought of getting the client culture was from the Request object.
After examining the HTTP Headers collection I found the Accept-Language header. It contains information about the user's preferred languages.
This is a sample Accept-Language header:
Accept-Language
bg-BG,en-US;q=0.7,ar-BH;q=0.3
The languages are explicitly defined in the browser and their order is determined. You are probably wondering what this q-thing means. According to the RFC 3282 (Content Language Headers) it specifies the language quality or in other words the language priority set in the client's browser. In the example above bg-BG (Bulgarian (Bulgaria) has highest priority then en-US (English (United States)) and the last preferred language is ar-BH (Arabic (Bahrain)).
The Accept-Language header lists all languages set in the browser in a comma separated list which makes it easy to extract each language.
From ASP.NET you can access this header using the Headers collection in the Request object - Request.Headers["Accept-Language"]. Then you can process it the way you like.
Also instead of using Request.Headers["Accept-Language"] you can simply use the HttpRequest.UserLanguages to get a sorted string array of client language preferences.
After examining the HTTP Headers collection I found the Accept-Language header. It contains information about the user's preferred languages.
This is a sample Accept-Language header:
Accept-Language
bg-BG,en-US;q=0.7,ar-BH;q=0.3
The languages are explicitly defined in the browser and their order is determined. You are probably wondering what this q-thing means. According to the RFC 3282 (Content Language Headers) it specifies the language quality or in other words the language priority set in the client's browser. In the example above bg-BG (Bulgarian (Bulgaria) has highest priority then en-US (English (United States)) and the last preferred language is ar-BH (Arabic (Bahrain)).
The Accept-Language header lists all languages set in the browser in a comma separated list which makes it easy to extract each language.
From ASP.NET you can access this header using the Headers collection in the Request object - Request.Headers["Accept-Language"]. Then you can process it the way you like.
Also instead of using Request.Headers["Accept-Language"] you can simply use the HttpRequest.UserLanguages to get a sorted string array of client language preferences.
Wednesday, July 1, 2009
Unveiling System.MDW
Let me explain an (unintuitive) Access/JET security feature: the workgroup file. The workgroup information file, or WIF, stores your user and group information. It stores the usernames and passwords. Each workgroup information file, or .MDW file, contains a unique set of IDs that Access uses for its security encryption. In fact each user has a 'PID' which, combined with their username and the workgroup PIDs, generates an unique code that Access uses to determine your permissions. So where am I going with this?
Every Access install, for every version of Access, uses a default workgroup file that has the same workgroup PIDs, the same username ("Admin") and the same PID for that user. So if you are trying to secure a database by modifying the default workgroup file, you're already out of luck! Anyone using another computer already has the appropriate set of PIDs, by default, to walk right through your security. So this is a big gotcha.
Access has a default workgroup file named 'System.MDW'. Depending on your version of Access and your OS version, this file can be stored in a multitude of places. For me (Access 97/Win2K) it is stored in C:\WINNT\SYSTEM32\System.MDW . Older versions of Access use one MDW file for an entire computer; newer versions are more multi-user savvy and will install a separate System.MDW file for each user in the system. New NT-based operating systems use the C:\WINDOWS folder by default. Older OS's (Win2K/NT4) use the C:\WINNT folder by default. In all cases (Access 97 and newer), you can find the file by searching for "System.MDW".
Obviously then, it is not intended that you use the provided-by-default workgroup file. What then shall you do? Create a new, custom MDW file with PIDs you specify. To create a new workgroup file, you can (again, depending on Access version) find and run WRKGADM.EXE or go to Tools->Security->Workgroup Administrator. For me, the file is located at: C:\WINNT\SYSTEM32\WRKGADM.EXE
I'm not going to run through securing your new workgroup file; the Access security FAQ does an excellent job already.
Now that you have a custom workgroup file for use, how do you go about getting Access to use it?
Shortcuts (.LNK files) - The proper way to open a database using Access/JET security - Use the command-line /wrkgrp parameter to specify the workgroup you will use for your secured database. This will always involve the creation of a custom shortcut. An example of the shortcut's 'Target' line is:
"C:\Program Files\Microsoft Office\Office\MSACCESS.EXE" "C:\atemp\dev\rq_fe.mdb" /wrkgrp "C:\atemp\dev\icg.mdw"
This would open the 'rq_fe.MDB' file using my custom 'icg.mdw' workgroup file.
Every Access install, for every version of Access, uses a default workgroup file that has the same workgroup PIDs, the same username ("Admin") and the same PID for that user. So if you are trying to secure a database by modifying the default workgroup file, you're already out of luck! Anyone using another computer already has the appropriate set of PIDs, by default, to walk right through your security. So this is a big gotcha.
Access has a default workgroup file named 'System.MDW'. Depending on your version of Access and your OS version, this file can be stored in a multitude of places. For me (Access 97/Win2K) it is stored in C:\WINNT\SYSTEM32\System.MDW . Older versions of Access use one MDW file for an entire computer; newer versions are more multi-user savvy and will install a separate System.MDW file for each user in the system. New NT-based operating systems use the C:\WINDOWS folder by default. Older OS's (Win2K/NT4) use the C:\WINNT folder by default. In all cases (Access 97 and newer), you can find the file by searching for "System.MDW".
Obviously then, it is not intended that you use the provided-by-default workgroup file. What then shall you do? Create a new, custom MDW file with PIDs you specify. To create a new workgroup file, you can (again, depending on Access version) find and run WRKGADM.EXE or go to Tools->Security->Workgroup Administrator. For me, the file is located at: C:\WINNT\SYSTEM32\WRKGADM.EXE
I'm not going to run through securing your new workgroup file; the Access security FAQ does an excellent job already.
Now that you have a custom workgroup file for use, how do you go about getting Access to use it?
Shortcuts (.LNK files) - The proper way to open a database using Access/JET security - Use the command-line /wrkgrp parameter to specify the workgroup you will use for your secured database. This will always involve the creation of a custom shortcut. An example of the shortcut's 'Target' line is:
"C:\Program Files\Microsoft Office\Office\MSACCESS.EXE" "C:\atemp\dev\rq_fe.mdb" /wrkgrp "C:\atemp\dev\icg.mdw"
This would open the 'rq_fe.MDB' file using my custom 'icg.mdw' workgroup file.
Thursday, May 14, 2009
Enabling CLR integration in SQL Server 2005
If you are working with SQL server CLR objects there’s a higher possibility that you might encounter the following error.
“Msg 6263, Level 16, State 1, Line 1
Execution of user code in the .NET Framework is disabled. Enable "clr enabled" configuration option”
To overcome this, you have to reconfigure the SQL server to enable CLR objects. To do that, you can use the following commands.
exec sp_configure 'clr_enable','1'
RECONFIGURE
Note : CLR objects only works with SQL server 2005 and later versions.
CLR Objects Tutorial
“Msg 6263, Level 16, State 1, Line 1
Execution of user code in the .NET Framework is disabled. Enable "clr enabled" configuration option”
To overcome this, you have to reconfigure the SQL server to enable CLR objects. To do that, you can use the following commands.
exec sp_configure 'clr_enable','1'
RECONFIGURE
Note : CLR objects only works with SQL server 2005 and later versions.
CLR Objects Tutorial
Wednesday, May 6, 2009
Using HP Bluetooth Devices with Microsoft Bluetooth Stack
I usually prefer to use the Microsoft Bluetooth stack (included with Windows XP SP2) instead of the WIDCOMM stack because it requires less recourse, is faster and also easier to use. The only thing missing is support for any Audio profile.
However, if you have a lot of HP notebooks or tablets, you normally can't use the Microsoft stack since it doesn't know the build-in "HP integrated module with Bluetooth wireless technology". But there is a way to do it anyway…
First, remove the WIDCOMM stack using Control Panel -> Add/Remove Programs. Next, restart you computer and open up "Device Manager" (execute Devmgmt.msc). The above noted device will appear as "Unknown device".
Next, open C:\WINDOWS\inf and open the file "BTH.inf" with Notepad. It will start with something like this:
Scroll down until you find the following lines:
Duplicate the last line and append it to the same section. Then change the PID as described below. The section should now look like this:
Note that we only have changed the last characters to the PID (Product ID) of the Bluetooth device. If you have a new laptop the PID might have changed. You can get this PID by double-clicking the device and using the details tab.
Save the BTH.INF, go back to Device Manager and select "Scan for Hardware changes". The device should now start to install. It might happen that the device is after reported as having a problem. If this happens, simple right-click it, select "Disable" and after that "Enable" again.
That should do the trick and you can use the Microsoft stack with the "HP integrated module with Bluetooth wireless technology".
Enjoy!
However, if you have a lot of HP notebooks or tablets, you normally can't use the Microsoft stack since it doesn't know the build-in "HP integrated module with Bluetooth wireless technology". But there is a way to do it anyway…
First, remove the WIDCOMM stack using Control Panel -> Add/Remove Programs. Next, restart you computer and open up "Device Manager" (execute Devmgmt.msc). The above noted device will appear as "Unknown device".
Next, open C:\WINDOWS\inf and open the file "BTH.inf" with Notepad. It will start with something like this:
Code:
; Microsoft Windows Bluetooth Driver INF ; Copyright (c) 2002 Microsoft Corporation
Code:
[HP.NT.5.1] "HP USB BT Transceiver [1.2]" = BthUsb, USB\Vid_03F0&Pid_0C24
Code:
[HP.NT.5.1] "HP USB BT Transceiver [1.2]"= BthUsb, USB\Vid_03F0&Pid_0C24
"HP USB BT Transceiver [Patched]" = BthUsb, USB\Vid_03F0&Pid_011D
Save the BTH.INF, go back to Device Manager and select "Scan for Hardware changes". The device should now start to install. It might happen that the device is after reported as having a problem. If this happens, simple right-click it, select "Disable" and after that "Enable" again.
That should do the trick and you can use the Microsoft stack with the "HP integrated module with Bluetooth wireless technology".
Enjoy!
Tuesday, February 24, 2009
Displaying custom assemblies in ".NET References" dialog of VS.NET 2005
The items in the ".NET References" dialog are not necessarily in the GAC. They are actually in another directory which is defined in the registry.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\Foo\
Set the value of "Default" key to the path of the common assembly folder.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\
Set the value of "Default" key to the path of the common assembly folder.
Friday, November 21, 2008
C# Nullable Numeric Data Types
What About .NET 1.1?
The nullable types described in this article were introduced to the C# programming language with version 2.0 of the .NET framework. In order to achieve similar results using earlier framework versions, the developer must create a new structure or class. Structures will be looked at in a later article.
Null Value
When a program works with numeric information, particularly when it utilises information in a database, it is often the case that a value is undefined. An example of this is when a series of simple yes / no questions is asked and the result of each question held in a Boolean format. After a question is answered, the Boolean value can be set to either true or false to indicate the result. However, before the answer is given what should the value hold? The answer is null.
Nullable Numeric Data Types
Null is a special value that represents information that has not yet been defined. When the C# language was originally defined, the value null existed but could not be applied to numeric variables. In .NET framework 2.0, Microsoft rectified this problem by introducing nullable versions of these data types. Prior to this, the developer would need to work around this problem using values that would not normally be used by the variable or by holding a Boolean value indicating whether the numeric variable should be considered as defined or not.
All of the basic numeric data types have nullable equivalents. There are several ways to declare a variable as a nullable type. The simplest and most readable method is to simply append a question mark (?) to the data type. The following example shows the declaration and assignment of several nullable variables:
int? nullableInt;
int? nullValue = null;
int? notNull = 123;
bool? answer1 = true;
bool? answer2 = false;
bool? answer3 = null;
You can see from the above example that creating a nullable variable is similar to creating a standard numeric variable. As with other numeric variables, a value must be assigned to a variable before it is used, even if that value is null. The following code produces an error if you attempt to compile it.
int? nullableInt;
int? copy = nullableInt; // Invalid as nullableInt is not yet assigned
Data Type Conversion
Numeric nullable data types include very similar implicit and explicit conversion between the various sizes of nullable integers and floating point values. Values can also be converted between their nullable and non-nullable versions. As you would expect, conversion between two incompatibly sized types requires a cast statement, as does casting from a nullable to a non-nullable type.
int standardInteger = 123;
int? nullableInteger;
decimal standardDecimal = 12.34M;
// Implicit conversion from int to int?
nullableInteger = standardInteger;
// Explicit conversion from int? to int
standardInteger = (int)nullableInteger;
// Explicit cast from decimal to int?
nullableInteger = (int?)standardDecimal;
Care must be taken when casting a nullable value as a non-nullable data type. If the value of the nullable data type is null, this cannot be represented in the destination value and a run-time error will occur. This can be avoided by checking if the value is set to null before attempting the conversion.
Arithmetic Operators
The standard arithmetic operators can be used with numeric nullable data types. However, if the value of any of the operands is null, the result will always be null regardless of any other values.
int? a = 55;
int? n = null;
int? result;
result = a * 2; // result = 110
result = a * n; // result = null
Boolean Operators
When using nullable Boolean data types, the binary standard Boolean logical operators can be used. Where both of the operands used are set to either true or false, the results of the operation are exactly the same as for non-nullable Booleans. Where one or both of the operands used in a logical operation are set to null, the result is usually null. There are two special cases where this does not happen. In a logic OR operation, if any value is true then the result is true, even if the other operand is null. For logical AND operations, if either value is false then the result is also false.
bool? result;
result = true & null; // result = null
result = false & null; // result = false
result = true | null; // result = true
result = false | null; // result = null
result = true ^ null; // result = null
result = false ^ null; // result = null
Relational Operators
The relational operators are all valid for use with nullable numeric data types. However, when the value being compared is null, the results are not always as expected. The equal to and not equal to operators are able to make comparisons with both numeric and null values. With all of the other relational operators, the result of the comparison is always false when a value being compared is null.
int? a = 55;
int? n = null;
bool result;
result = a == n; // result = false
result = a != n; // result = true
result = n == null; // result = true
result = a > n; // result = false
result = a < result =" false" style="font-weight: bold;">Testing for Null Values
The previous section showed the use of the relational operators with numeric nullable types. Included in the examples you can see that it is possible to use the equal to or not equal to operators to test if the value of a variable is null. In addition to these operators, the nullable data types define several properties and methods for checking if the value is null and for retrieving the value where it is not.
HasValue Property
The first property of the numeric nullable types of interest is the HasValue property. This property simply returns a Boolean value indicating whether the nullable variable contains a real value or a null value. To access the value of a property, the member access operator is used. This is simply a full stop (period or dot) placed between the name of the variable and the name of the member (property or method) to be used. The following example shows the HasValue property used to set a non-nullable value to the value of a nullable type with a default value of -1 where the nullable variable has no value.
int? a = 10;
int? n = null;
int result;
bool checkIfNull;
checkIfNull = a.HasValue; // checkIfNull = true
result = checkIfNull ? (int)a : -1; // result = 10
checkIfNull = n.HasValue; // checkIfNull = false
result = checkIfNull ? (int)n : -1; // result = -1
Value Property
The numeric nullable data types include a second property that can be used to retrieve the value from a variable as a non-nullable type. This provides the same effect as a cast from a nullable type to its non-nullable counterpart. As with this type of cast however, a run-time error will occur should the value of the variable be null. The previous example can therefore also be written as follows:
int? a = 10;
int? n = null;
int result;
bool checkIfNull;
checkIfNull = a.HasValue; // checkIfNull = true
result = checkIfNull ? a.Value : -1; // result = 10
checkIfNull = n.HasValue; // checkIfNull = false
result = checkIfNull ? n.Value : -1; // result = -1
result = n.Value; // This causes a run-time error.
GetValueOrDefault Method
The GetValueOrDefault method is available to all of the numeric nullable data types. This method provides all of the functionality of the previous example in a single line of code. The method can be called in two ways. If the method is used without a parameter then the numeric value of the nullable data is returned. If the variable in question has a null value, a zero is returned instead. The second manner to call the method includes passing a parameter to specify the default value to replace nulls with. As with all methods, the parameter is held in parentheses with an empty pair of parentheses should no parameter be specified.
int? a = 10;
int? n = null;
int result;
result = a.GetValueOrDefault(); // result = 10
result = n.GetValueOrDefault(); // result = 0
result = n.GetValueOrDefault(-1); // result = -1
The Null Coalescing Operator
The null coalescing operator is a new operator introduced as a part of the .NET framework version 2.0. This operator can be used on any numeric nullable data type and also other nullable data types that have yet to be introduced in the C# Fundamentals tutorial.
The null coalescing operator tests the value of a variable to check if it is null. If the value is not null then the variable's value is returned unaffected. If the variable is null however, a substitute value is provided as a second operand. The operator provides similar functionality to the GetValueOrDefault method with the benefit that it can be used on data that does not provide this functionality. The operator's symbol is a double question mark (??).
int? a = 10;
int? n = null;
int result;
result = a ?? -1; // result = 10
result = n ?? -1; // result = -1
Citation here
The nullable types described in this article were introduced to the C# programming language with version 2.0 of the .NET framework. In order to achieve similar results using earlier framework versions, the developer must create a new structure or class. Structures will be looked at in a later article.
Null Value
When a program works with numeric information, particularly when it utilises information in a database, it is often the case that a value is undefined. An example of this is when a series of simple yes / no questions is asked and the result of each question held in a Boolean format. After a question is answered, the Boolean value can be set to either true or false to indicate the result. However, before the answer is given what should the value hold? The answer is null.
Nullable Numeric Data Types
Null is a special value that represents information that has not yet been defined. When the C# language was originally defined, the value null existed but could not be applied to numeric variables. In .NET framework 2.0, Microsoft rectified this problem by introducing nullable versions of these data types. Prior to this, the developer would need to work around this problem using values that would not normally be used by the variable or by holding a Boolean value indicating whether the numeric variable should be considered as defined or not.
All of the basic numeric data types have nullable equivalents. There are several ways to declare a variable as a nullable type. The simplest and most readable method is to simply append a question mark (?) to the data type. The following example shows the declaration and assignment of several nullable variables:
int? nullableInt;
int? nullValue = null;
int? notNull = 123;
bool? answer1 = true;
bool? answer2 = false;
bool? answer3 = null;
You can see from the above example that creating a nullable variable is similar to creating a standard numeric variable. As with other numeric variables, a value must be assigned to a variable before it is used, even if that value is null. The following code produces an error if you attempt to compile it.
int? nullableInt;
int? copy = nullableInt; // Invalid as nullableInt is not yet assigned
Data Type Conversion
Numeric nullable data types include very similar implicit and explicit conversion between the various sizes of nullable integers and floating point values. Values can also be converted between their nullable and non-nullable versions. As you would expect, conversion between two incompatibly sized types requires a cast statement, as does casting from a nullable to a non-nullable type.
int standardInteger = 123;
int? nullableInteger;
decimal standardDecimal = 12.34M;
// Implicit conversion from int to int?
nullableInteger = standardInteger;
// Explicit conversion from int? to int
standardInteger = (int)nullableInteger;
// Explicit cast from decimal to int?
nullableInteger = (int?)standardDecimal;
Care must be taken when casting a nullable value as a non-nullable data type. If the value of the nullable data type is null, this cannot be represented in the destination value and a run-time error will occur. This can be avoided by checking if the value is set to null before attempting the conversion.
Arithmetic Operators
The standard arithmetic operators can be used with numeric nullable data types. However, if the value of any of the operands is null, the result will always be null regardless of any other values.
int? a = 55;
int? n = null;
int? result;
result = a * 2; // result = 110
result = a * n; // result = null
Boolean Operators
When using nullable Boolean data types, the binary standard Boolean logical operators can be used. Where both of the operands used are set to either true or false, the results of the operation are exactly the same as for non-nullable Booleans. Where one or both of the operands used in a logical operation are set to null, the result is usually null. There are two special cases where this does not happen. In a logic OR operation, if any value is true then the result is true, even if the other operand is null. For logical AND operations, if either value is false then the result is also false.
bool? result;
result = true & null; // result = null
result = false & null; // result = false
result = true | null; // result = true
result = false | null; // result = null
result = true ^ null; // result = null
result = false ^ null; // result = null
Relational Operators
The relational operators are all valid for use with nullable numeric data types. However, when the value being compared is null, the results are not always as expected. The equal to and not equal to operators are able to make comparisons with both numeric and null values. With all of the other relational operators, the result of the comparison is always false when a value being compared is null.
int? a = 55;
int? n = null;
bool result;
result = a == n; // result = false
result = a != n; // result = true
result = n == null; // result = true
result = a > n; // result = false
result = a < result =" false" style="font-weight: bold;">Testing for Null Values
The previous section showed the use of the relational operators with numeric nullable types. Included in the examples you can see that it is possible to use the equal to or not equal to operators to test if the value of a variable is null. In addition to these operators, the nullable data types define several properties and methods for checking if the value is null and for retrieving the value where it is not.
HasValue Property
The first property of the numeric nullable types of interest is the HasValue property. This property simply returns a Boolean value indicating whether the nullable variable contains a real value or a null value. To access the value of a property, the member access operator is used. This is simply a full stop (period or dot) placed between the name of the variable and the name of the member (property or method) to be used. The following example shows the HasValue property used to set a non-nullable value to the value of a nullable type with a default value of -1 where the nullable variable has no value.
int? a = 10;
int? n = null;
int result;
bool checkIfNull;
checkIfNull = a.HasValue; // checkIfNull = true
result = checkIfNull ? (int)a : -1; // result = 10
checkIfNull = n.HasValue; // checkIfNull = false
result = checkIfNull ? (int)n : -1; // result = -1
Value Property
The numeric nullable data types include a second property that can be used to retrieve the value from a variable as a non-nullable type. This provides the same effect as a cast from a nullable type to its non-nullable counterpart. As with this type of cast however, a run-time error will occur should the value of the variable be null. The previous example can therefore also be written as follows:
int? a = 10;
int? n = null;
int result;
bool checkIfNull;
checkIfNull = a.HasValue; // checkIfNull = true
result = checkIfNull ? a.Value : -1; // result = 10
checkIfNull = n.HasValue; // checkIfNull = false
result = checkIfNull ? n.Value : -1; // result = -1
result = n.Value; // This causes a run-time error.
GetValueOrDefault Method
The GetValueOrDefault method is available to all of the numeric nullable data types. This method provides all of the functionality of the previous example in a single line of code. The method can be called in two ways. If the method is used without a parameter then the numeric value of the nullable data is returned. If the variable in question has a null value, a zero is returned instead. The second manner to call the method includes passing a parameter to specify the default value to replace nulls with. As with all methods, the parameter is held in parentheses with an empty pair of parentheses should no parameter be specified.
int? a = 10;
int? n = null;
int result;
result = a.GetValueOrDefault(); // result = 10
result = n.GetValueOrDefault(); // result = 0
result = n.GetValueOrDefault(-1); // result = -1
The Null Coalescing Operator
The null coalescing operator is a new operator introduced as a part of the .NET framework version 2.0. This operator can be used on any numeric nullable data type and also other nullable data types that have yet to be introduced in the C# Fundamentals tutorial.
The null coalescing operator tests the value of a variable to check if it is null. If the value is not null then the variable's value is returned unaffected. If the variable is null however, a substitute value is provided as a second operand. The operator provides similar functionality to the GetValueOrDefault method with the benefit that it can be used on data that does not provide this functionality. The operator's symbol is a double question mark (??).
int? a = 10;
int? n = null;
int result;
result = a ?? -1; // result = 10
result = n ?? -1; // result = -1
Citation here
Wednesday, November 12, 2008
Say Hello to Gmail Voice & Video Chat
I'm a big user of Gmail chat. Being able to switch from email to chat as needed, all within the same app, is really great for productivity. But people can only type so fast, and even with our new emoticons, there are still some things that just can't be expressed in a chat message.
That's why today Google is launching voice and video chat -- right inside Gmail. They've tried to make this an easy-to-use, seamless experience, with high-quality audio and video -- all for free. All you have to do is download and install the voice and video plugin and it'll take care of the rest. And in the spirit of open communications, designed this feature using Internet standards such as XMPP, RTP, and H.264, which means that third-party applications and networks can choose to interoperate with Gmail voice and video chat.
Once you install the plugin, to start a video chat, just click on the "Video & more" menu at the bottom of your Gmail chat window, and choose "Start video chat." You'll have a few seconds to make sure you look presentable while it's ringing, and then you'll see and hear your friend live, right from within Gmail. You can click the "pop-out" iconto make the video larger, or click the fullscreen iconin the upper left-hand corner for a fully immersive experience. See this all in action in the video below.
Team is spread between Google offices in the US and Sweden, and video has really changed the way we work. Collaborating across continents and timezones is a fact of life, and it sure is easier (and greener) to click "Start video chat" than to get on a plane! And when I do have to visit another office, I can use Gmail voice and video chat to check in with my family.
They've just started to roll out Gmail voice and video chat for both PCs and Macs, so if you don't see it right away, don't worry -- it could take a day or so for this feature to be available in all Gmail and Google Apps accounts. If you want to download the plugin right away, visit http://gmail.com/videochat.
Citation here
That's why today Google is launching voice and video chat -- right inside Gmail. They've tried to make this an easy-to-use, seamless experience, with high-quality audio and video -- all for free. All you have to do is download and install the voice and video plugin and it'll take care of the rest. And in the spirit of open communications, designed this feature using Internet standards such as XMPP, RTP, and H.264, which means that third-party applications and networks can choose to interoperate with Gmail voice and video chat.
Once you install the plugin, to start a video chat, just click on the "Video & more" menu at the bottom of your Gmail chat window, and choose "Start video chat." You'll have a few seconds to make sure you look presentable while it's ringing, and then you'll see and hear your friend live, right from within Gmail. You can click the "pop-out" iconto make the video larger, or click the fullscreen iconin the upper left-hand corner for a fully immersive experience. See this all in action in the video below.
Team is spread between Google offices in the US and Sweden, and video has really changed the way we work. Collaborating across continents and timezones is a fact of life, and it sure is easier (and greener) to click "Start video chat" than to get on a plane! And when I do have to visit another office, I can use Gmail voice and video chat to check in with my family.
They've just started to roll out Gmail voice and video chat for both PCs and Macs, so if you don't see it right away, don't worry -- it could take a day or so for this feature to be available in all Gmail and Google Apps accounts. If you want to download the plugin right away, visit http://gmail.com/videochat.
Citation here
Custom shortcuts in the Windows XP dialog box
This will guide you in setting custom “shortcuts” in the Windows XP “Save As” dialog box.
Note: This also works in Windows Vista Ultimate Edition, but not sure about the other versions of Vista.
1. Click Start and select Run. In the Run window enter gpedit.msc and click OK.
2. The Group Policy editor will appear.
3. In the left window select the + (plus sign) next to User Configuration to expand the list. Next select the plus sign next to Administrative Templates and then Windows Explorer. Finally, select the Common Open File Dialog entry.
4. Double-click the Items displayed in Places Bar entry in the main Group Policy window.
5. The Items displayed in Places Bar Properties window will open.
6. Select Enabled and then enter in the locations you’d like to have displayed in the Save As dialog box. You need to enter the full path to the location for the shortcuts to work.
For example, if you want to have a shortcut to your My Documents folder, enter in:
C:\Documents and Settings\Your User Name\My Documents\
7. Once you’ve entered in all the locations you’d like to appear in the Save As window, click Apply and then OK.
8. Back in the Group Policy editor, you should see that the Items displayed in Places Bar is now Enabled. Close the Group Policy editor.
9. Test it out by saving a file. You should now have the new shortcuts displayed.
10. The same shortcuts will be used in the Open dialog box, not just the Save As box.
Citation here
Note: This also works in Windows Vista Ultimate Edition, but not sure about the other versions of Vista.
1. Click Start and select Run. In the Run window enter gpedit.msc and click OK.
2. The Group Policy editor will appear.
3. In the left window select the + (plus sign) next to User Configuration to expand the list. Next select the plus sign next to Administrative Templates and then Windows Explorer. Finally, select the Common Open File Dialog entry.
4. Double-click the Items displayed in Places Bar entry in the main Group Policy window.
5. The Items displayed in Places Bar Properties window will open.
6. Select Enabled and then enter in the locations you’d like to have displayed in the Save As dialog box. You need to enter the full path to the location for the shortcuts to work.
For example, if you want to have a shortcut to your My Documents folder, enter in:
C:\Documents and Settings\Your User Name\My Documents\
7. Once you’ve entered in all the locations you’d like to appear in the Save As window, click Apply and then OK.
8. Back in the Group Policy editor, you should see that the Items displayed in Places Bar is now Enabled. Close the Group Policy editor.
9. Test it out by saving a file. You should now have the new shortcuts displayed.
10. The same shortcuts will be used in the Open dialog box, not just the Save As box.
Citation here
Subscribe to:
Posts (Atom)