Maximum C#

October 26, 2009

What’s New in the BCL in .NET 4 Beta 2

Filed under: Programming — Tags: , , , , , , — .:: Bishoy™ ::. @ 11:59 AM

Visual Studio 2010 and .NET Framework 4 Beta 2 are now available to download.  .NET 4 Beta 2 contains several new BCL features and enhancements in addition to what was included in .NET 4 Beta 1.  Many of these improvements were added in large part due to specific feedback and suggestions reported by customers through Microsoft Connect.

Summary of New BCL Functionality in .NET 4 Beta 2

  • Complex Number
  • Location
  • IObservable<T>
  • Stream.CopyTo
  • Guid.TryParse, Version.TryParse, and Enum.TryParse<T>
  • Enum.HasFlag
  • String.Concat and String.Join overloads that take IEnumerable<T>
  • String.IsNullOrWhiteSpace
  • Environment.SpecialFolder additions
  • Environment.Is64BitProcess and Environment.Is64BitOperatingSystem
  • Path.Combine params support
  • TimeSpan Globalized Formatting and Parsing
  • Stopwatch.Restart
  • StringBuilder.Clear
  • IntPtr and UIntPtr Addition and Subtraction operators
  • ServiceProcessInstaller.DelayedAutoStart
  • ObservableCollection<T> moved to System.dll

Complex Number

System.Numerics.Complex represents a complex number comprised of a real number and imaginary number.  Complex supports both rectangular coordinates (real and imaginary) and polar coordinates (magnitude and phase measured in radians) and supports arithmetic and trigonometric operations.  Complex numbers are used in a number of areas including high-performance computing, graphing and charting, electrical engineering (e.g. Fourier transforms), and other numerical applications.

Location

System.Device.Location (which can be found in System.Device.dll) enables .NET applications running on Windows 7 to determine the current geo-location (e.g. latitude/longitude) of the device.  Windows 7 supports a number of different location sensors, including GPS devices and WWAN radios, and automatically handles transitioning between different sensors — if multiple sensors are available — to provide the most accurate data for the current situation. .NET applications will be able to use this new API to access the following data (if available): latitude, longitude, altitude, horizontal and vertical accuracy, course, speed, and civic address (i.e. country/region, state/province, city, postal code, street, building, floor level).  Note that we are planning to make some changes to the shape of the location API between Beta 2 and RC, so please keep this in mind as you evaluate and use the Beta 2 location API in apps.  A separate blog post will provide more details on the planned changes for RC.

IObservable<T>

System.IObservable<T> and System.IObserver<T> provide a general mechanism for push-based notifications and can be used to represent push-based, or observable, collections.  Anyone familiar with design patterns will recognize these interfaces as representations of the well-known observer pattern.  IObservable<T> opens up the doors to some exciting new paradigms for event-based and asynchronous programming on .NET.  A great example of this is the Reactive Framework (RX), which is a library of extension methods (not included as part of .NET 4) that implement the LINQ Standard Query Operators and other useful stream transformation functions for IObservable<T>.  F# first-class events also support IObservable<T> and F# includes a library of Observable operators similar to those available in RX.  Imagine being able to do LINQ-style queries against events; this is just one of the kinds of things that IObservable<T> enables.  To help grasp the power of IObservable<T>, I encourage you to watch the Channel 9 videos of Erik Meijer introducing RX and Wes Dyer and Kim Hamilton discussing IObservable<T> in the BCL.

Stream.CopyTo

When working with Streams, how many times have you had to write the following boiler-plate code to read from one stream and write the contents to another stream?

Stream source = ...;
Stream destination = ...;
byte[] buffer = new byte[4096];
int read;
while ((read = source.Read(buffer, 0, buffer.Length)) != 0) {
    destination.Write(buffer, 0, read);
}

In .NET 4, you no longer have to write this code.  We’ve added a new CopyTo method to Stream that allows you to simply write:

Stream source = ...;
Stream destination = ...;
source.CopyTo(destination);

Guid.TryParse, Version.TryParse, and Enum.TryParse<T>

We’ve added TryParse to System.Guid, System.Version, and System.Enum.  Enum.TryParse is generic, a nice improvement over the existing non-generic Parse method, which leads to much cleaner code.

On previous versions of .NET, to parse an enum value, you’d write something like this:

try {
    string value = Console.ReadLine();
    FileOptions fo = (FileOptions)Enum.Parse(typeof(FileOptions), value);     // Success
}
catch {
    // Error
}

On .NET 4, you can use the new generic TryParse method:

string value = Console.ReadLine();
FileOptions fo;
if (Enum.TryParse(value, out fo)) {
    // Success
}

Enum.HasFlag

We’ve added a new convenience method to System.Enum that makes it super easy to determine if a flag is set on a particular Flags enum, without having to remember how to use the bitwise operators.  This also allows for more readable code.

ConsoleModifiers cm = ConsoleModifiers.Alt | ConsoleModifiers.Shift;
bool hasAlt1 = (cm & ConsoleModifiers.Alt) == ConsoleModifiers.Alt; // using bitwise operators
bool hasAlt2 = cm.HasFlag(ConsoleModifiers.Alt); // using HasFlag

String.Concat and String.Join overloads that take IEnumerable<T>

We’ve added new overloads of String.Concat and String.Join that take IEnumerable<T>, adding to the existing overloads that take arrays.  This means you can pass any collection that implements IEnumerable<T> to these APIs without having to first convert the collection into an array.  We’ve also added “params” support to the existing array-based String.Join overload, which allows you to write more succinct code.  In C#:

String.Join(", ", new string[] { "A", "B", "C", "D" }); // you used to have to write this
String.Join(", ", "A", "B", "C", "D"); // now you can write this

String.IsNullOrWhiteSpace

This new convenience method is similar to the existing IsNullOrEmpty method, but in addition to checking if the string is null or empty, it also checks to see if the string only consists of white-space characters, as defined by Char.IsWhiteSpace.  It works great for Code Contract preconditions.

Environment.SpecialFolder additions

We’ve added a number of new values to the Environment.SpecialFolder enum:

AdminTools, CDBurning , CommonAdminTools , CommonDesktopDirectory , CommonDocuments , CommonMusic , CommonOemLinks , , CommonPictures , CommonProgramFilesX86 , CommonPrograms , CommonStartMenu , CommonStartup , CommonTemplates , CommonVideos , Fonts , LocalizedResources , MyVideos , NetworkShortcuts , PrinterShortcuts , ProgramFilesX86 , Resources , SystemX86 , Templates , UserProfile , Windows

We’ve also added a new overload to Environment.GetFolderPath that takes a new SpecialFolderOption enum, allowing you to specify some additional options, such as “Create” (to create the directory if it doesn’t exist) and “DoNotVerify” (to just return the path without checking if it exists, which can help reduce lag time if the directory is on a network share).

Environment.Is64BitProcess and Environment.Is64BitOperatingSystem

These new convenience APIs make it easy to determine the bitness of the current process and operating system.  Environment.Is64BitProcess is equivalent to calling IntPtr.Size == 8.  Environment.Is64BitOperatingSystem will tell you if the underlying OS is 64-bit.  Note that it is possible for Environment.Is64BitProcess to return false and Environment.Is64BitOperatingSystem to return true if the process is a 32-bit process running on a 64-bit operating system under WOW64.

Path.Combine params support

Have you ever had to nest calls to Path.Combine like this:

Path.Combine("dir1", Path.Combine("dir2", Path.Combine("dir3", "dir4")));

With .NET 4, you can simply write:

Path.Combine("dir1", "dir2", "dir3", "dir4");

TimeSpan Globalized Formatting and Parsing

In previous versions of .NET, TimeSpan only supported a single culture-agnostic format for formatting and parsing.  This meant if you called ToString on a French machine the output would not match culture settings, making the application appear not to be globalized.  This is often noticeable in apps that display results from SQL databases that use the frequently used Time column type, because SQL’s Time maps to TimeSpan in .NET.  For example:

Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine(new TimeSpan(0, 1, 1, 1, 1));
Console.WriteLine(12.34);

Output:

01:01:01.0010000
12,34

The output from TimeSpan.ToString is a culture-agnostic format so it uses a ‘.’ as the decimal separator, whereas Double uses ‘,’ based on the current culture.

In .NET 4, System.TimeSpan now supports formatting and parsing based on culture settings via new overloads of ToString, Parse, and TryParse, and new ParseExact and TryParseExact methods.  The default ToString overload still behaves the same for backwards compatibility, outputting a constant, culture-agnostic format, but the new overloads allow you to specify additional culture-sensitive formats.  You can pass the “g” format (general format) to the new ToString overload to specify a culture-sensitive format:

Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine(new TimeSpan(0, 1, 1, 1, 1).ToString("g"));
Console.WriteLine(12.34);

Output:

01:01:01,0010000
12,34

Stopwatch.Restart

This is a new convenience method that is equivalent to calling Stopwatch.Reset followed by Stopwatch.Start.

StringBuilder.Clear

In previous versions of .NET, you could clear StringBuilder by setting the Length property to 0.  This isn’t very discoverable, so we’ve added StringBuilder.Clear as a more discoverable equivalent.

IntPtr and UIntPtr Addition and Subtraction operators

Adding an offset to an IntPtr or UIntPtr can be error prone and often introduces subtle bugs on 64-bit machines if not done correctly.  .NET 4 includes addition and subtraction operators on these types, along with Add and Subtract methods, to help prevent these kinds of errors.

ServiceProcessInstaller.DelayedAutoStart

.NET-based services that start automatically can now set a new DelayedAutoStart property to true (recommended), which will delay auto-starting the service until after other auto-start services are started plus a short delay to improve system boot performance when running on Vista or greater.

ObservableCollection<T> moved to System.dll

We’ve type-forward System.Collections.ObjectModel.ObservableCollection<T>, System.Collections.ObjectModel.ReadOnlyObservableCollection<T>, and System.Collections.Specialized.INotifyCollectionChanged from WindowsBase.dll (a WPF assembly) to System.dll.  This allows you to use these collections without taking a dependency on a WPF assembly and enables a cleaner separation between model and view.

 

This post was taken from the BCL Team Blog and Edited to be more clear and compact for speed reading

October 15, 2009

What is S.O.L.I.D.?

Filed under: Programming — Tags: , — .:: Bishoy™ ::. @ 11:52 AM

S.O.L.I.D. is a collection of best-practice, object-oriented design principles which can be applied to your design, allowing you to accomplish various desirable goals such as loose-coupling, higher maintainability, intuitive location of interesting code, etc.

S.O.L.I.D. is an acronym for some principles (which are, themselves acronyms).

SRP: Single Responsibility Principle (read more)


THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.


OCP: Open Closed Principle (read more)


SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION BUT CLOSED FOR MODIFICATION.


LSP: Liskov Substitution Principle (read more)


FUNCTIONS THAT USE … REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.


ISP: Interface Segregation Principle (read more)


CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE


DIP: Dependency Inversion Principle (read more)


A. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS
B. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS

October 5, 2009

The Liskov Substitution Principle (LSP )

Filed under: Programming — Tags: , , — .:: Bishoy™ ::. @ 12:41 PM

What a title to put an article on it, but after reading about that principle I had that feeling that sharing it will benefit someone out there.

that principle is talking about Good practice in Object-Oriented software Design and its definition is the following:

FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE
CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES
WITHOUT KNOWING IT.

 

What does that mean in simple words?

If you have the following class diagram (I will rely on a function in the base class instead of providing a new class for the purpose of demonstrating) :

ClassDiagram1

 

in that diagram you have a hierarchy for the brush classes that include a base abstract class called “Brush” and inherited from it the “Solid”, “Gradient” and the “Texture”

In the “Brush” class we have one method which draw on the supplied “surface” argument using the brush’s attributes, and in our case we have that code that do the drawing:

public void Draw(Graphics surface)
{
    if (this is Solid)
    {
        // draw with solid color
    }
    else if (this is Gradient)
    {
        // draw a gradient
    }
    else if (this is Texture)
    {
        // draw with a texture bitmap
    }
}

That Code is a very bad practice and will definitely lead to serious  problems later on when you need to add more classes that inherit from the base “Brush” class.

think of what will you do if you have 20 types of brushes ?? what about a 100 or 200 types ?? , maybe in that particular example the real world does not offer that amount of brushes .. but for demo purpose you should think of what that method/function will look like if you have hundreds of inherited classes of the base “Brush’” class ……. Exactly yes it will be a big mess and maintaining that method will be a headache later when that application evolves.

So what should we do about it ???

the best solution here in my opinion is to rely on inheritance and the magical “Virtual / Override” mechanism

so our first best practice here is to distribute that function’s responsibility to the class hierarchy and leave it “open for extensibility but closed for modifications”  as the best practices say.

and here is the new diagram after fixing it:

ClassDiagram1

and the code for the base class will be as following:

public virtual void Draw(Graphics surface)
{
    // draw on the surface
}

Note the “Virtual’ operator that decorates our function definition, that means that our inherited classes are free to “Override” this particular method and/or extend it with new or different logic or behavior

and here is the code in the descendant classes:

public class Texture : Brush
{
    public override void Draw(System.Drawing.Graphics surface)
    {
        // we can use the next statement to call the parent’s draw method
        base.Draw(surface);
        // extend the drawing with a concrete Texture Brush
    }
}

public class Solid : Brush
{
    public override void Draw(System.Drawing.Graphics surface)
    {
        // create a very different logic for the brush and do not use the parent’s code
    }
}

as we can see that “Texture” executed “base.Draw(surface)” before it proceeds with its own logic and that means that it will let the parent do its work first and then it will complete hereafter it with its own logic, and in the “Solid” it never called its Base/parent and it will provide a totally different logic for the drawing.

Final Note

one more thing here for you to note is that you need to watch out for changes you will provide in behavior because in “Design by contract” principle you MUST preserve all logic and validation that is expected from the parent class in all its children and you should not alter the default parent behavior unless it is not going to break any of its client’s usages.

such as if the Draw method is supposed to Fire an Event after finishing the drawing, any of its descendants when they override that method MUST fire that event no matter what they do because the other classes will rely on that event to do other related logic.

kick it on DotNetKicks.com

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.