Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, September 27, 2009

LINQ

LINQ is Language Integrated Query. It is pronounced “link” and not ‘lin-queue”. It is a Microsoft .NET 3.5 component that adds native data querying capabilities to .NET languages using a syntax similar to SQL. One can do databases, XML, arrays, etc.

var results = from c in SomeCollection
where c.SomeProperty = conditionvalue
select new (c.SomeProperty, c.SomeOtherProperty);
foreach (var result in results)

Reflection


Reflection is a functional extension to the object-oriented programming paradigm. It includes self-examination, self-modification, and self-replication. It is commonly used by programs which require the ability to examine or modify the runtime behavior of applications. This is typically accomplished by dynamically assigning program code at runtime.

E.g. In C#, here's how you would achieve reflection:
//Without reflection
Foo foo = new Foo();
foo.Hello();

//With reflection
Type t = Assembly.GetCallingAssembly().GetType("FooNamespace.Foo");
t.InvokeMember("Hello", BindingFlags.InvokeMethod, null, Activator.CreateInstance(t), null);

Reflection is powerful, but should not be used indiscriminately. The following concerns should be kept in mind when accessing code via reflection:
  •  Performance Overhead
Because reflection involves types that are dynamically resolved, certain optimizations cannot be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
  •  Security Restrictions
Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context.
  •  Exposure of Internals
Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods; the use of reflection can result in unexpected side-effects. This may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

P.S. Since this is an advanced feature of .Net framework, if you can use this in your application, you can call yourself an "advanced programmer"! :)

FxCop


FxCop is an application that analyzes managed code assemblies (code that targets the .NET Framework CLR) and reports information about the assemblies, such as possible design, localization, performance, and security improvements.

So to say, FxCop essentially analyzes the compiled object code, and not the original source code. It uses MSIL parsing, and callgraph analysis to inspect assemblies for defects in the following areas:
  •  Correctness
  •  Library design
  •  Localization
  •  Naming conventions
  •  Performance
  •  Security

FxCop is intended for class library developers; however, anyone creating applications that should conform to .NET Framework best practices will benefit. FxCop is also useful as an educational tool for those who are new to the .NET Framework or are unfamiliar with the .NET Framework Design Guidelines.

FxCop is designed to be fully integrated into the software development cycle and is distributed as both a fully featured application with a GUI (FxCop.exe) for interactive work, and a command-line tool (FxCopCmd.exe) suitable for use as part of automated build processes or integrated with Microsoft Visual Studio®.NET as an external tool.

Keywords of FxCop:
  •  Target: FxCop analyzes programming elements in managed assemblies, called targets. It provides an informational report containing messages about the targets, including suggestions on how to improve the source code used to generate them.
  •  Rule: A rule is managed code that can analyze targets and return a message about its findings. Rule messages identify any relevant programming and design issues and, when possible, supply information on how to fix the target. FxCop represents the checks it performs during an analysis as rules.

FxCop integrates with the Visual Studio IDE to enable developers to analyze the source code at the time of coding and is a freeware downloadable from:

internal - A keyword in C#


internal” is a new access modifier for types and type members, in addition to the existing private, public and protected. Internal types or members are accessible only within files in the same assembly. When “protected internal” is used, it keeps access limited to the current assembly or types derived from the containing class.

public class BaseClass
{
    // Only accessible within the same assembly
    internal static int count = 0;
}

A common use of internal access is in component-based development because it enables a group of components to cooperate in a private manner without being exposed to the rest of the application code.
E.g. a framework for building graphical user interfaces could provide Control and Form classes that co-operate using members with internal access. Since these members are internal, they are not exposed to code that is using the framework.

It is an error to reference a member with internal access outside the assembly within which it was defined.

Assembly1.cs
// Compile with: /target:library
internal class BaseClass
{
   public static int nCount = 0;
}

// Assembly2.cs
// Compile with: /reference:Assembly1.dll
class TestAccess
{
   static void Main()
   {
      BaseClass myBase = new BaseClass();       // Error: CS0122; 'member' is inaccessible
// due to its protection level
   }
}

sealed - A keyword in C#


When applied to a class, the “sealed” modifier prevents other classes from inheriting from this class. Sealed classes are primarily used to prevent derivation. Because they can never be used as a base class, some run-time optimizations can make calling sealed class members slightly faster.

using System;
sealed class MyClass
{
    int x;
    int y;
}

It is an error to use the abstract modifier with a sealed class, because an abstract class must be inherited by a class that provides an implementation of the abstract methods or properties.

You can also use the “sealed” modifier on a method or property that overrides a virtual method or property in a base class. This enables you to allow classes to derive from your class and prevent them from overriding specific virtual methods or properties. This negates the virtual aspect of the member for any further derived class. This is accomplished by putting the sealed keyword before the override keyword in the class member declaration. When applied to a method or property, the sealed modifier must always be used with override.

public class D : C
{
    public sealed override void DoWork() { }
}

Structs are implicitly sealed; therefore, they cannot be inherited.

To determine whether to seal a class, method, or property, you should generally consider the following two points:
  •  The potential benefits that deriving classes might gain through the ability to customize your class.
  •  The potential that deriving classes could modify your classes in such a way that they would no longer work correctly or as expected.

params (A keyword in C#)


Arrays are used to pass a variable number of parameters to a member. C# provides the "params" keyword which lets you specify a method parameter that takes an argument where the number of arguments is variable. No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.
E.g.
public class MyClass
{
    public static void UseVariableParameters(params int[] list)
    {
        for (int i = 0; i < list.Length; i++)
        {
            Console.WriteLine("{0}th parameter: {1}", i, list[i]);
        }
    }
}

public static void DemonstrateVariableParameters()
{
    MyClass.UseVariableParameters(1, 2, 3, 4, 5);
}

Passing variable number of parameters to methods should be used judicially. Follow guidelines given below for appropriate use of variable arrays for parameters:
  •  Use params keyword to array parameters if you expect the end users to pass a small number of elements.
  •  Do not use params arrays if the caller would almost always already have the input in an array.
  •  Do not use params arrays if the array is modified by the member taking the params array parameter.
  •  Do try to order parameters to make it possible to use the params keyword.
  •  Consider providing special overloads and code paths for calls with a small number of arguments in extremely performance-sensitive APIs.
  •  By following this guideline, you can avoid creating arrays when a member is called with a small number of arguments. The parameter names should be a singular form of the array parameter followed by a numeric suffix. The following code example shows a member signature that follows this guideline.
public static void WriteLine(string format, object arg0, object arg1, object arg2)
  •  Be aware that null could be passed as a params array argument.

Generics - A new feature in CLR and C# version 2.0


The .NET Framework 2.0 introduces generics to allow you to create flexible, reusable code. Language features collectively known as generics act as templates that allow classes, structures, interfaces, methods, and delegates to be declared and defined with unspecified or generic type parameters instead of specific types. Actual types are specified later when the generic is used. The new System.Collections.Generic namespace provides support for strongly typed collections. System.Nullable is a standard representation of optional values.

Use generic types to maximize code reuse, type safety, and performance. The most common use of generics is to create collection classes. You can create your own generic interfaces, classes, methods, events and delegates. Generic classes may be constrained to enable access to methods on particular data types.

E.g.
Stack - Represents a variable size last-in-first-out(LIFO) collection of instances of the same arbitrary type.

Stack numbers = new Stack();
numbers.Push("One");
numbers.Push("Two");
numbers.Push("Three");
numbers.Push("Four");

// A stack can be enumerated without disturbing its contents.
foreach (string number in numbers)
{
      Console.WriteLine(number);
}

Information on the types used in a generic data type may be obtained at run-time by means of reflection.

C# Indexers

Indexers permit instances of a class or struct to be indexed in the same way as arrays. Indexers are similar to properties except that their accessors take parameters. To declare an indexer on a class or struct, use the “this” keyword as shown below:

// Indexer declaration
public int this[int index]    
{
    // get and set accessors
}

The type of an indexer and the type of its parameters must be at least as accessible as the indexer itself. The signature of an indexer consists of the number and types of its formal parameters. It does not include the indexer type or the names of the formal parameters. If you declare more than one indexer in the same class, they must have different signatures. An indexer value is not classified as a variable; therefore, it is not possible to pass an indexer value as a ref or out parameter.

// Using a string as an indexer value
class DayCollection
{
    string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };

    // This method finds the day or returns -1
    private int GetDay(string testDay)
    {
        int i = 0;
        foreach (string day in days)
        {
            if (day == testDay)
            {
                return i;
            }
            i++;
        }
        return -1;
    }

    // The get accessor returns an integer for a given string
    public int this[string day]
    {
        get
        {
            return (GetDay(day));
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        DayCollection week = new DayCollection();
        System.Console.WriteLine(week["Fri"]);
        System.Console.WriteLine(week["Made-up Day"]);
    }
}

*  Indexers enable objects to be indexed in a similar way to arrays.
*  A get accessor returns a value. A set accessor assigns a value.
*  The “this” keyword is used to define the indexers.
*  The value keyword is used to define the value being assigned by the set indexer.
*  Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.
*  Indexers can be overloaded.
*  Indexers can have more than one formal parameter, for example, when accessing a two-dimensional array.

There are two main ways in which the security and reliability of indexers can be improved:
*  Always ensure that your code performs range and type checks when setting and retrieving values from any buffer or array accessed by the indexers.
*  Set the accessibility of the get and set accessors to be as restrictive as is reasonable. This is important for the set accessor in particular.