using …

Pure C#

Nisan, 2009 için Arşiv

Exception Lovers

Yazan: esersahin 27/04/2009

http://www.vijaymukhi.com/documents/books/csadv/chap9.htm

Chapter 9

Miscellaneous

Members

There are only two types of entities that can contain members, namely, types and namespaces. These members can be accessed using the same rules i.e. the name of an entity to be followed by a dot ‘.’ and then the member name to be given. This cardinal rule is never ever broken.

All derived classes inherit every member of a base class with the exception of constructors and destructors. This rule applies to private members also. Regardless of inheriting all the members, the base class members may/may not be accessible to the derived class members. Thus, the access modifiers have nothing to contribute to inheritance. In other words, the rules of inheritance ignore the access modifiers.

If a namespace is not specified for a member, it belongs to a default namespace called the global namespace. Like it or not, all members are part and parcel of a namespace. They cannot exist out of a namespace under any circumstance. It makes logical sense creating our own namespaces thereby avoiding the unnecessary clutter in the global namespace with the members we create.

The word int is an alias for System.Int32. A variable of type int is internally known as System.Int32. The basic types like int are internally not known by their name but something else that is entirely different.

a.cs

public class zzz

{

public static void Main()

{

System.Type t = typeof(int);

System.Console.WriteLine(t.FullName);

}

}

Output

System.Int32

The above example reconfirms the point we enumerated a little earlier. The compiler does not understand an int as a data type but knows all about a structure called System.Int32 instead. When we coached you earlier about the compiler understanding about data types like int at birth, what we truly meant was that there exists structures in the System namespace relating to these datatypes. The compiler is informed well in advance about the one-to-one connection between the alias name and their structures. When we get some time on our hand, we will list out and explain all the members of this structure.

To explain the above example, we use a keyword typeof, which accepts the name of a class or structure. This returns an object that looks like Type. The Type object consists of methods and properties that publish everything you ever wanted to know about a type but were afraid to ask. We are only using one member called FullName to prove our hypothesis.

a.cs

class zzz

{

public static void Main()

{

string yyy = “hell”;

string s = yyy;

System.Type t = typeof(yyy);

System.Console.WriteLine(s);

System.Console.WriteLine(t);

}

}

class yyy

{

}

Output

hell

yyy

typeof expects the name of a class as a parameter. C# allows a variable name and a class name to be the same. At the line s = yyy, C# assumes yyy to be the name of a variable. yyy is considered to be a class name and t is initialised to the typeof returned by it. Thus, C# uses a lot of intelligence to read between the lines.

Our resident astrologer informed us that at least 1.54234 per cent of our book must be copied from the documentation. To make sure that no ill luck befalls us, we copied a couple of lines from it. Thus an sbyte is an alias for System.Sbyte,byte System.Byte, short System.Int16, ushort System.UInt16, uint System.UInt32, long System.Int64, ulong System.UInt64, char System.Char, float System.Single, double System.Double, decimal System.Decimal, and, finally, bool System.Boolean. Enums are simple derived from System.Enum and are simple constants. Object is an alias for System.Object and string System.String. Interfaces are only derived from object and arrays form System.Array. Delegates are from System.Delegate. These have been mentioned earlier, they have been placed here only as a ready reckner.

Member Lookup

A member lookup is a way by means of which the meaning of a name in a type is determined or figured out. A class can have base classes and all classes have one base class object. The compiler first figures out all the names that match in the class and base class. We can have a constant and a property with the same name in a base class and derived class. We mentioned this earlier, but it merits repeating. If we ever have an override modifier in front of a member name, then this name has overridden the earlier name in the base class. It is thus removed from the list as it is a different name. If the name is a constant, field, property, event, type or enum, it hides all the members of the base class. If it is function, then all non-methods are hidden in the base class. The end result could either be a single non-method name or a series of methods. Anything else is an error.

Every known entity is derived from object. We have mentioned this at least a hundred times already. Value types cannot derive from any other type except object unlike classes and interfaces. However, arrays and delegates are derived from System.Array and System.Delegate respectively.

Name Resolution

After the giving a namespace and a period, we can either use the name of another namespace or the name of a type. If we start, however, with the name of a type, then what follows can be one of the following. Either a type as in a nested types, or a method, a static property, static readonly field or a static field, static event, constant, or finally an enum. Anything else signals an error.

a.cs

class zzz

{

public static void Main()

{

aaa aaa;

aaa bbb = aaa.bbb();

aaa ccc = aaa.ccc;

}

}

class aaa

{

public static aaa ccc = new aaa();

public static aaa bbb()

{

return new aaa();

}

}

If you want to confuse any person using your code, use the above code. The above explanation clearly states that we can create a constant, field, local variable or a parameter with the same name as the name of a type. Thus, we have a class aaa which contains two members. One is a static field called ccc and the other is a static function bbb which returns an aaa type. In Main, we create a variable called aaa, same as the data type. Then we call static members of the class aaa using the name of the type. All this leeway is given to us because we are allowed access to static members of the class aaa without any ambiguity.

An invocation expression can either be a method group or a delegate. Nothing else can be executable. If the function returns void, the result is nothing. Thus, an expression which results in nothing cannot obviously be the operand of a operator, it can only be used a statement.

A method group can either be one method or a group of methods. The parameter types decide which of the methods would be chosen. To execute a certain method, the compiler starts with the type before the method. It then proceeds up the inheritance chain and finds an applicable, accessible, non-override method. If it finds more than one, it uses overload resolution to decide the best one.

Constructor Signatures

a.cs

public class zzz

{

public static void Main()

{

int i = 3;

yyy a = new yyy(ref i);

int j;

yyy b = new yyy(out j);

System.Console.WriteLine(i + ” ” + j);

}

}

class yyy

{

public yyy(ref int p)

{

p = 100;

}

public yyy(out int q)

{

q = 1000;

}

}

Compiler Error

a.cs(18,8): error CS0663: ‘.ctor’ cannot define overloaded methods which differ only on ref and out

a.cs(14,8): (Location of symbol related to previous error)

A constructor cannot define overloaded methods differing only on ref or out. The above logic makes sense as a constructor is nothing but a function that is called automatically at birth. It is in no way different from any other functions that we have worked with.

a.cs

public class zzz

{

public static void Main()

{

yyy a = new yyy(1,2,3);

}

}

class yyy

{

public yyy(params int [] q)

{

foreach ( int i in q)

System.Console.Write(i + ” ” );

}

}

Output

1 2 3

We can use the params modifier to our hearts content in displaying the parameters to the constructors.

a.cs

public class zzz

{

public static void Main()

{

yyy a = new yyy(1,2,3);

}

}

class yyy

{

public yyy(params int [] q)

{

foreach ( int i in q)

System.Console.Write(i + ” ” );

}

public yyy ( int i, int j , int k)

{

System.Console.Write(“int”);

}

}

Output

int

However, the params modifier is given the last priority by the compiler. If there is an exact match, a one-to-one with the parameters in the constructors, the compiler gives precedence to it and the params is ignored for good. For three ints, the constructor with three parameters will be called and for any other combination of ints, the params constructor will be called.

a.cs

public class zzz

{

public static void Main()

{

yyy a = new yyy(1,2,3);

}

}

class yyy

{

public yyy(int p, int p1,int p2,params int [] q)

{

}

public yyy ( int i, int j , int k)

{

System.Console.Write(“int”);

}

}

Output

int

Regardless of both the constructors matching very closely, the compiler yet does not give us any error. This is because it treats the params as a second class citizen of the world. We would never like to be in the shoes of a params parameter.

This

This is only permitted to be used in three places namely a constructor, instance method and an instance accessor.

a.cs

class zzz

{

public static void Main()

{

yyy a = new yyy();

}

}

class yyy

{

public yyy()

{

System.Console.WriteLine(this);

if ( this is yyy)

System.Console.WriteLine(“yes yyy”);

if ( this is zzz)

System.Console.WriteLine(“yes zzz”);

}

public static implicit operator string (yyy a)

{

return “hi”;

}

}

Compiler Warning

a.cs(13,6): warning CS0183: The given expression is always of the provided (‘yyy’) type

a.cs(15,6): warning CS0184: The given expression is never of the provided (‘zzz’) type

Output

hi

yes yyy

A this in a constructor is considered to be the value of the data type of the class that contains the constructor. In the above program, the is operator is used to reconfirm the above statement. Also, the implicit string operator is called as the this has to be converted to a string for WriteLine function. Ditto for instance members and accessors. Comment out the string operator and the output will be

yyy

yes yyy

For a constructor in a structure, the rules change dramatically. Here it is a variable. Like earlier, it stands for a reference to the structure it is placed in, but a major difference is that it is classified as an out parameter. Thus, all the members of the structure must be initialized before we leave the constructor.

In the case of an instance method, everything remains the same as above, but now it behaves as a ref parameter instead of an out. Being a ref parameter, someone else is responsible for initializing the variable. The function can access all the instance variables in the structure and also infringe the benefit of changing them if we so choose to. A this is not used on anything remotely connected with static or in variable initializer of a field declaration. A program relating to this is as follows.

a.cs

class zzz

{

int j = 10;

int i = this.j;

public static void Main()

{

}

}

Compiler Error

a.cs(4,9): error CS0027: Keyword this is not available in the current context

This variable is available only in certain places within a class type and can be assumed as the first parameter to the functions in the type. If we have a function abc accepting two ints as a parameter, we would write it as abc(int i, int j). In class yyy, the function gets rewritten as abc( yyy this, int i, int j).

This is passed as the first parameter and refers to the class the function resides in. As the programming language C++ called this reference variable as this, C# copied the same concept but with a small change for structures.

Base

We use the variable base in a completely different manner. A function in the base class gets hidden by the same function name in a derived class.

a.cs

class zzz

{

public static void Main()

{

aaa a = new aaa();

a.abc();

}

}

class yyy

{

public virtual void abc()

{

System.Console.WriteLine(“yyy abc”);

}

}

class xxx : yyy

{

public override void abc()

{

System.Console.WriteLine(“xxx abc”);

base.abc();

}

}

class aaa : xxx

{

public override void abc()

{

System.Console.WriteLine(“aaa abc”);

base.abc();

}

}

Output

aaa abc

xxx abc

yyy abc

The base variable has absolutely nothing to do with the modifiers new and override. It simply calls the function in the base class without bothering about new or override to its existing function. It simply does not care at all. Thus, using base, we can call a function from the base class irrespective of the modifiers on it.

We will get an error if base is used in an abstract function. Base, similar to this, is valid only in a constructor, instance method or accessor. All the methods from the viewpoint of base, are non virtual.

Writing base.abc will caste the this pointer of the current class to its lower class, i.e. the base class. Internally base.abc in class aaa derived from class xxx becomes ((xxx)this).abc and ditto for an indexer access.

Thus, base and this are conceptually similar, except that one acts on a base class, the other on a derived class.

a.cs

class zzz

{

public static void Main()

{

xxx a = new xxx();

a.abc();

}

}

class yyy

{

public virtual void abc()

{

System.Console.WriteLine(“yyy abc”);

}

}

class xxx : yyy

{

public override void abc()

{

System.Console.WriteLine(“xxx abc”);

((yyy)this).abc();

}

}

Do not run the above program as it will take you to a trip to the moon. Just does not stop at all. All that we said earlier was only conceptually true. You cannot replace a base with a this. The programming language contains both of them and cannot be used interchangeably.

A struct variable has a free default constructor always available. Thus unlike a class initialization, which explicitly initializes the instance variables to zero, the constructor in the case of the struct does the same.

Name Hiding

Name hiding occurs when we inherit from a class or struct and erroneously or otherwise, we introduce a similar name as that in the base class. A constant, field, property, event, or type hides the base class members with the same name.

a.cs

public class zzz

{

public static void Main()

{

yyy a = new yyy();

System.Console.WriteLine(a.i);

a.i = 100;

System.Console.WriteLine(a.i);

}

}

class yyy : xxx

{

public int i = 3;

}

class xxx

{

public const int i = 10;

}

Compiler Warning

a.cs(13,12): warning CS0108: The keyword new is required on ‘yyy.i’ because it hides inherited member ‘xxx.i’

Output

3

100

A million years ago, someone somewhere in the world created a class called xxx. That gentleman, then, added one const member called i. For some reason, we decided to derive from class xxx.

We are allowed to create our own variable i notwithstanding the fact that it was declared to be a const in class xxx. Other than a warning issued by the compiler, we are allowed complete freedom in using whatever names we like in our derived classes, thus oblivious to what the base class has given.

a.cs

public class zzz

{

public static void Main()

{

yyy a = new yyy();

a.i();

}

}

class yyy : xxx

{

public void i()

{

System.Console.WriteLine(“hi”);

}

}

class xxx

{

public const int i = 10;

}

Output

hi

As stated earlier, we have total freedom in doing what we like within the derived class. In the above example, the function i has nothing to do with the const i in class xxx. The compiler does send you a feeble protest in the form of a simple warning but that can be ignored with no loss of life or limb. The same rules apply to indexers also. As repeated earlier, operators can never hide each other ever.

Concealing an inherited member does not issue any error as it would then prevent evolving any base classes independently. Lets us explain why a warning and not an error.

Let us assume that we are deriving from a base class that has a function called pqr. We now decided to create an abc function in the derived class. After a while, the next version of the base class, for some reason, introduces a new function called abc. At that moment, all derived classes from the base class should not break or give an error. In the scheme of things followed by C#, they are different functions and making changes to a base class does not invalidate existing derived classes at all.

Functions

There are five places in the C# language where we can place executable code. These places are constructors, methods, properties, indexers and user-defined operators. Anywhere else, and you permission from the silicon god that is not very forthcoming. Function members are not members of a namespace and thus we can only place the above in a type. You cannot have global functions that are not associated with a type. We cannot use ref and out parameters for indexers, properties or operators. These have to be value parameters only.

a.cs

class zzz

{

public static void Main()

{

zzz a = new zzz();

int i = 0;

a.abc(i++,i++,i++);

System.Console.WriteLine(i);

}

public void abc( int x, int y, int z)

{

System.Console.WriteLine(x + ” ” + y + ” ” + z);

}

}

Output

0 1 2

3

The parameters to a function are read in the order they are written, from left to right. Thus even though we are using a postfix notation, i++, the compiler uses the current value of i to initialize parameter x in function abc, and then increase i by one. Thus, i now has a value of one, that is what the parameter y is initialized to and then it is increased by one. This z becomes two and at the end of the function invocation variable i has a value of three.

Object Elements

a.cs

class zzz

{

public static void Main()

{

byte [] b = new byte[2];

b[1] = 10;

yyy a = new yyy();

System.Console.WriteLine(b[a]);

}

}

class yyy

{

public static implicit operator int(yyy a)

{

return 1;

}

}

Output

10

If we remove the overloaded operator int, we get the following error.

Compiler Error

a.cs(8,28): error CS0029: Cannot implicitly convert type ‘yyy’ to ‘int’

The variable we use in the [] brackets is called the element access and must be one of the following data types namely int, uint, long, ulong or any type that can be implicitly converted to the above type. Thus, without the operator int which was responsible for converting the yyy to an int, we got the above error. On returning 1 in the operator, the array variable becomes b[1].

a.cs

class zzz {

public static void Main()

{

byte [] b = new byte[2];

b[1] = 10;

yyy a = new yyy();

System.Console.WriteLine(b[a]);

}

}

class yyy

{

public static implicit operator uint(yyy a)

{

System.Console.WriteLine(“uint”);

return 1;

}

public static implicit operator long(yyy a)

{

System.Console.WriteLine(“long”);

return 1;

}

}

Output

uint

10

Rules, rules everywhere, but not a drop to drink. The element access of an array as stated earlier must either be an int, uint, long or a ulong. The above order must be followed. The compiler checks for the operators in the above order and on finding the very first match, it uses that operator. It stops short in its tracks and does not complain that it could use both the above operators.

It is one of the few cases where although both the operators were applicable, it does not give us an error. In the above types, a short is not mentioned. Recall that sometime back, we spoke of a short being converted into a int. Operators are allowed to throw an exception. If one takes place then the processing stops.

a.cs

class zzz

{

public static void Main()

{

byte [] b = null;

System.Console.WriteLine(b[1]);

}

}

Output

Unhandled Exception: System.NullReferenceException: Value null was found where an instance of an object was required.

at zzz.Main()

Like a delegate, if we try and access any null object, an exception is thrown. No compile time checks are performed for null as the value. Maybe the next version of the compiler will check for a null and it is on our wish list for Santa Claus. Ditto if we try and exceed the bounds of an array. The exception thrown is IndexOutOfRangeException instead.

a.cs

class zzz {

public static void pqr(ref object x)

{

System.Console.WriteLine(“pqr ” + x);

}

public static void abc(object x)

{

System.Console.WriteLine(“abc ” + x);

}

public static void Main() {

object[] a = new object[2];

object[] b = new string[2];

abc(a[0]);

abc(b[1]);

pqr(ref a[0]);

pqr(ref b[1]);

}

}

Output

abc

abc

pqr

Unhandled Exception: System.ArrayTypeMismatchException: Exception of type System.ArrayTypeMismatchException was thrown.

at zzz.Main()

The rules of array co-variance allow an array to be populated by any data type provided there exist an implicit conversion between them. Array b is an array of objects and there exists an implicit conversion from a string to an object. Hence, we can initialize an array of objects to an array of strings. The array object b is not an array of objects but one that comprises of an array of strings. The compile time data type may be that of an object but the run time data type must be that of a string.

Whenever we have a ref parameter being passed a reference, we use an array instead. The compiler is smart enough to perform a run time check on the data type being passed as an array now can hold dual data types. In the last call to function pqr, we are passing b[0] which at compile time is an object but at run time is a string. Thus, an exception is thrown. Remember exceptions can only be thrown at run time. This holds true only for ref parameters and not value parameters.

a.cs

class zzz {

public static void Main() {

}

int x;

void abc( int a)

{

x = 1;

if (a > 10)

{

float x = 1.0;

}

}

}

Compiler Error

a.cs(10,7): error CS0136: A local variable named ‘x’ cannot be declared in this scope because it would give a different meaning to ‘x’, which is already used in a ‘parent or current’ scope to denote something else

a.cs(10,11): error CS0029: Cannot implicitly convert type ‘double’ to ‘int’

A block is represented by a {} braces. Any variable or identifier created within a block must primarily be unique within that block. Then it must also be unique within the immediate enclosing block. Thus in both blocks, the name must be unique and therefore refer to the same entity. The meaning of the identifier must remain the same within the block.

We get an error in the above program as in the outer block we have an int x and in the inner block, within the if statement we have another variable called x again. The second error comes in handy as it very clearly states that it assumes the variable x to be an int within the if statement. The golden rule again. We cannot have a variable with the same name in the inner and outer block. If we remove the statement x = 1 from the above program we will get a slightly different error as follows.

Compiler Error

a.cs(10,11): error CS0664: Literal of type double cannot be implicitly converted to type ‘float’; use an ‘F’ suffix to create a literal of this type

a.cs

class zzz

{

public static void Main()

{

}

int x;

void abc( int a)

{

if (a > 10)

{

x = 1;

}

else

{

double x = 1.0;

}

}

}

Compiler Warning

a.cs(15,8): warning CS0219: The variable ‘x’ is assigned but its value is never used

a.cs(6,5): warning CS0169: The private field ‘zzz.x’ is never used

The compiler gives us no errors as the variable x created outside of a function in the outer block is not used in the main function block. It is only used in the if statement. Since the else block of the if statement, which is at the same level is not executed, the compiler adjourns after giving a few warnings.

a.cs

class zzz

{

public static void Main()

{

}

int x;

void abc( int a)

{

x = 3;

if (a > 10)

{

x = 1;

}

else

{

double x = 1.0;

}

}

}

Compiler Error

a.cs(16,8): error CS0136: A local variable named ‘x’ cannot be declared in this scope because it would give a different meaning to ‘x’, which is already used in a ‘parent or current’ scope to denote something else

a.cs(16,12): error CS0029: Cannot implicitly convert type ‘double’ to ‘int’

If we knowingly initialize the instance variable x in the function abc, we are using the one created in the outer block. So, we are not allowed to recreate the same variable x the inner block under any circumstance. If you comment the line with x=1 or double x=1.0, the compiler will give you warnings. This proves that the compiler is confused on the variable it should work with while initializing x to 1 as there are two variables available by the same name.

a.cs

class zzz

{

public static void Main()

{

}

void abc( bool a)

{

if (a)

{

int i = 0;

}

int i = 3;

}

}

Compiler Error

a.cs(12,5): error CS0136: A local variable named ‘i’ cannot be declared in this scope because it would give a different meaning to ‘i’, which is already used in a ‘child’ scope to denote something else

a.cs(12,5): error CS0103: The name ‘i’ does not exist in the class or namespace ‘zzz’

What we forgot to inform you earlier is that the reverse is not true. That is, a variable created in an inner block or scope cannot be defined outside the parent or outer scope. This is in contrast to the above explanation.

a.cs

class zzz

{

public static void Main()

{

}

void abc( bool a)

{

if (a)

{

int i = 0;

}

if ( a)

{

int i = 3;

}

}

}

We get no error above as the two if statements are at the same level and the variables created within the blocks are independent of each other. They do not interfere with each other.

The above explanation, called the rules of invariant, apply only to simple names. It is not applicable to member access, an example of this is seen below.

a.cs

class zzz

{

public static void Main()

{

}

int x;

void abc( int x)

{

this.x = x;

}

}

We have two variables called x in the above program. One is an instance variable and the other is a parameter to a function. Within the function abc, the parameter variable x hides the instance variable. If we want to access the instance variable, however, we have to preface the variable name with this. It is therefore, a good idea to preface all instance variables with the reserved word this.

Indexers

a.cs

class zzz

{

public static void Main()

{

yyy a = new yyy();

xxx b = new xxx();

a[1] = b;

System.Console.WriteLine(a[1]);

}

}

class yyy

{

public xxx this[int i]

{

get

{

return new xxx();

}

set

{

}

}

}

class xxx

{

}

Output

xxx

An indexer can store any value provided it is a class, struct or interface. However, the return value of an indexer is not part of its signature. We can have only one return type but multiple types of parameters.

Throw

a.cs

class zzz {

public static void Main()

{

throw null;

}

}

Output

Unhandled Exception: System.NullReferenceException: Exception of type System.NullReferenceException was thrown.

at zzz.Main()

The keyword null is like a rubber man. Fits everywhere. If we throw a null, the actual exception thrown is NullReferenceException.

a.cs

class zzz

{

public static void Main()

{

throw ;

}

}

Compiler Error

a.cs(5,1): error CS0156: A throw statement with no arguments is not allowed outside of a catch clause

A throw can be used without the name of an expression only in a catch. This is one of the few error messages that actually sound English-like. Hope, he is not sacked for committing blasphemy.

a.cs

class zzz

{

public static void Main()

{

try

{

throw null;

}

catch ( System.Exception e)

{

System.Console.WriteLine(“catch”);

throw;

}

}

}

Output

catch

Unhandled Exception: System.NullReferenceException: Exception of type System.NullReferenceException was thrown.

at zzz.Main()

In this program, a throw is used without any parameters in a catch statement. It is actually a short form of the throw and it throws the same exception that the catch invokes.

In this case, the earlier throw showed a NullReferenceException Exception and the inner throw throws the same exception. Also, remember the end point of a throw can never be reached even by a miracle. Exception propagation is the process of transferring control from a throw to one of the exception handlers that may exist.

a.cs

using System;

class zzz

{

void abc()

{

try

{

pqr();

}

catch (Exception e)

{

Console.WriteLine(“abc: ” + e.Message);

e = new Exception(“abc”);

Console.WriteLine(“abc: ” + e.Message);

throw;

}

}

void pqr() {

throw new Exception(“pqr”);

}

public static void Main()

{

zzz a = new zzz();

try {

a.abc();

}

catch (Exception e) {

Console.WriteLine(“Main: ” + e.Message);

}

}

}

Output

abc: pqr

abc: abc

Main: pqr

The throw by itself re-throws the same exception. The exception parameter is like a value variable and even though we are re initializing it, the original remains the same. Thus the message displayed by e.Message does not change from pqr to abc ever. The change is only affected within the catch block as shown by the WriteLine function. The behaviour is the same as that of a value variable.

a.cs

class zzz

{

public static void Main()

{

try

{

}

}

}

Compiler Error

a.cs(8,1): error CS1524: Expected catch or finally

Man cannot live on love alone. So also, a try needs either a catch or a finally or both to live. The variable offered to a catch is just like a parameter to a function and it can be definitely assigned like a value parameter. It also unfortunately dies at the end of the catch. Life-time and visibility do not exceed the catch block!

a.cs

class zzz

{

public static void Main()

{

try {}

catch ( System.Exception ) {}

}

}

We do not have to supply the exception name in a catch. If we do not, as in the above program, there is no known way of figuring out what exception took place. Common sense dictates that we give the exception a name and try and use it in the code written in the catch.

a.cs

class zzz

{

public static void Main()

{

try {}

catch () {}

}

}

Compiler Error

a.cs(6,8): error CS1015: An object, string, or class type expected

a.cs(6,10): error CS1026: ) expected

What is mandatory however, is the name of the exception class. The documentation says it is possible to have no parameters and the catch is then called a general catch. Does not work as advertised for us. The documentation also claims that it has to be the last. No such luck.

a.cs

class zzz

{

public static void Main()

{

try {}

catch (System.NullReferenceException e) {}

catch (System.NullReferenceException e) {}

}

}

Compiler Error

a.cs(7,8): error CS0160: A previous catch clause already catches all exceptions of this or a super type (‘System.NullReferenceException’)

You cannot have two catch statements of the same type as the compiler examines them in textual order, first come first serve. The first match is the chosen exception handler, thus the second catch would never be called making it unreachable. This is a no-no as the compiler will have to execute a catch that is unreachable.

a.cs

class zzz

{

public static void Main()

{

zzz a = new zzz();

try {}

finally

{

goto aa ;

System.Console.WriteLine(“aa”);

aa:

goto bb ;

}

bb:

System.Console.WriteLine(“bb”);

}

}

Compiler Warning

a.cs(10,1): warning CS0162: Unreachable code detected

Compiler Error

a.cs(12,1): error CS0157: Control cannot leave the body of a finally clause

We can use a goto statement to jump around within a finally. It would be an act of God to jump out of a finally. The same rules hold for a break or continue. No leaving a finally under any circumstance including a natural calamity. If we have forgotten to tell you this earlier, no returns help either.

a.cs

class zzz

{

public static void Main()

{

zzz a = new zzz();

try

{

goto aa ;

}

finally

{

System.Console.WriteLine(“aa”);

}

aa:

System.Console.WriteLine(“bb”);

}

}

Output

aa

bb

No such restrictions apply to a try block. Everything that we taught you earlier can also be used in a try block. The only proviso is that we have to first execute code in the finally block before leaving the try block.

Yazı kategorisi: C#, Exception, Try Catch | » yorum bırak;

sp_executesql (Transact-SQL)

Yazan: esersahin 27/04/2009

http://msdn.microsoft.com/en-us/library/ms188001(SQL.90).aspx

Updated: 5 December 2005

Executes a Transact-SQL statement or batch that can be reused many times, or one that has been built dynamically. The Transact-SQL statement or batch can contain embedded parameters.

Topic link icon Transact-SQL Syntax Conventions

sp_executesql [ @stmt = ] stmt
[
    {, [@params=] N'@parameter_name data_type [ OUT | OUTPUT ][,...n]' }
     {, [ @param1 = ] 'value1' [ ,...n ] }
]
[ @stmt = ] stmt
Is a Unicode string that contains a Transact-SQL statement or batch. stmt must be either a Unicode constant or a Unicode variable. More complex Unicode expressions, such as concatenating two strings with the + operator, are not allowed. Character constants are not allowed. If a Unicode constant is specified, it must be prefixed with an N. For example, the Unicode constant N’sp_who’ is valid, but the character constant ’sp_who’ is not. The size of the string is limited only by available database server memory. On 64-bit servers, the size of the string is limited to 2 GB, the maximum size of nvarchar(max).

ms188001.note(en-US,SQL.90).gifNote:
stmt can contain parameters having the same form as a variable name, for example: N'SELECT * FROM HumanResources.Employee WHERE EmployeeID = @IDParameter'

Each parameter included in stmt must have a corresponding entry in both the @params parameter definition list and the parameter values list.

[ @params = ] N’@parameter_name data_type [ ,... n ]
Is one string that contains the definitions of all parameters that have been embedded in stmt. The string must be either a Unicode constant or a Unicode variable. Each parameter definition consists of a parameter name and a data type. n is a placeholder that indicates additional parameter definitions. Every parameter specified in stmt must be defined in @params. If the Transact-SQL statement or batch in stmt does not contain parameters, @params is not required. The default value for this parameter is NULL.

[ @param1 = ] value1
Is a value for the first parameter that is defined in the parameter string. The value can be a Unicode constant or a Unicode variable. There must be a parameter value supplied for every parameter included in stmt. The values are not required when the Transact-SQL statement or batch in stmt has no parameters.

[ OUT | OUTPUT ]
Indicates that the parameter is an output parameter. text, ntext, and image parameters can be used as OUTPUT parameters, unless the procedure is a common language runtime (CLR) procedure. An output parameter that uses the OUTPUT keyword can be a cursor placeholder, unless the procedure is a CLR procedure.

n
Is a placeholder for the values of additional parameters. Values can only be constants or variables. Values cannot be more complex expressions such as functions, or expressions built by using operators.

0 (success) or non-zero (failure)
Returns the result sets from all the SQL statements built into the SQL string.
sp_executesql has the same behavior as EXECUTE with regard to batches, the scope of names, and database context. The Transact-SQL statement or batch in the sp_executesql stmt parameter is not compiled until the sp_executesql statement is executed. The contents of stmt are then compiled and executed as an execution plan separate from the execution plan of the batch that called sp_executesql. The sp_executesql batch cannot reference variables declared in the batch that calls sp_executesql. Local cursors or variables in the sp_executesql batch are not visible to the batch that calls sp_executesql. Changes in database context last only to the end of the sp_executesql statement.

sp_executesql can be used instead of stored procedures to execute a Transact-SQL statement many times when the change in parameter values to the statement is the only variation. Because the Transact-SQL statement itself remains constant and only the parameter values change, the SQL Server query optimizer is likely to reuse the execution plan it generates for the first execution.

ms188001.note(en-US,SQL.90).gifNote:
To improve performance use fully qualified object names in the statement string.

sp_executesql supports the setting of parameter values separately from the Transact-SQL string as shown in the following example.

DECLARE @IntVariable int;
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);

/* Build the SQL string one time.*/
SET @SQLString =
     N'SELECT EmployeeID, NationalIDNumber, Title, ManagerID
       FROM AdventureWorks.HumanResources.Employee
       WHERE ManagerID = @ManagerID';
SET @ParmDefinition = N'@ManagerID tinyint';
/* Execute the string with the first parameter value. */
SET @IntVariable = 197;
EXECUTE sp_executesql @SQLString, @ParmDefinition,
                      @ManagerID = @IntVariable;
/* Execute the same string with the second parameter value. */
SET @IntVariable = 109;
EXECUTE sp_executesql @SQLString, @ParmDefinition,
                      @ManagerID = @IntVariable;

Output parameters can also be used with sp_executesql. The following example retrieves a job title from the AdventureWorks.HumanResources.Employee table and returns it in the output parameter @max_title.

DECLARE @IntVariable int;
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE @max_title varchar(30);

SET @IntVariable = 197;
SET @SQLString = N'SELECT @max_titleOUT = max(Title)
   FROM AdventureWorks.HumanResources.Employee
   WHERE ManagerID = @level';
SET @ParmDefinition = N'@level tinyint, @max_titleOUT varchar(30) OUTPUT';

EXECUTE sp_executesql @SQLString, @ParmDefinition, @level = @IntVariable, @max_titleOUT=@max_title OUTPUT;
SELECT @max_title;

Being able to substitute parameters in sp_executesql offers the following advantages to using the EXECUTE statement to execute a string:

  • Because the actual text of the Transact-SQL statement in the sp_executesql string does not change between executions, the query optimizer will probably match the Transact-SQL statement in the second execution with the execution plan generated for the first execution. Therefore, SQL Server does not have to compile the second statement.
  • The Transact-SQL string is built only one time.
  • The integer parameter is specified in its native format. Casting to Unicode is not required.
Requires membership in the public role.

A. Executing a simple SELECT statement

The following example creates and executes a simple SELECT statement that contains an embedded parameter named @level.

EXECUTE sp_executesql
          N'SELECT * FROM AdventureWorks.HumanResources.Employee
          WHERE ManagerID = @level',
          N'@level tinyint',
          @level = 109;

B. Executing a dynamically built string

The following example shows using sp_executesql to execute a dynamically built string. The example stored procedure is used to insert data into a set of tables that are used to partition sales data for a year. There is one table for each month of the year that has the following format:

CREATE TABLE May1998Sales
    (OrderID int PRIMARY KEY,
    CustomerID int NOT NULL,
    OrderDate  datetime NULL
        CHECK (DATEPART(yy, OrderDate) = 1998),
    OrderMonth int
        CHECK (OrderMonth = 5),
    DeliveryDate datetime  NULL,
        CHECK (DATEPART(mm, OrderDate) = OrderMonth)
    )

This sample stored procedure dynamically builds and executes an INSERT statement to insert new orders into the correct table. The example uses the order date to build the name of the table that should contain the data, and then incorporates that name into an INSERT statement.

ms188001.note(en-US,SQL.90).gifNote:
This is a simple example for sp_executesql. The example does not contain error checking and does not include checks for business rules, such as guaranteeing that order numbers are not duplicated between tables.
CREATE PROCEDURE InsertSales @PrmOrderID INT, @PrmCustomerID INT,
                 @PrmOrderDate DATETIME, @PrmDeliveryDate DATETIME
AS
DECLARE @InsertString NVARCHAR(500)
DECLARE @OrderMonth INT

-- Build the INSERT statement.
SET @InsertString = 'INSERT INTO ' +
       /* Build the name of the table. */
       SUBSTRING( DATENAME(mm, @PrmOrderDate), 1, 3) +
       CAST(DATEPART(yy, @PrmOrderDate) AS CHAR(4) ) +
       'Sales' +
       /* Build a VALUES clause. */
       ' VALUES (@InsOrderID, @InsCustID, @InsOrdDate,' +
       ' @InsOrdMonth, @InsDelDate)'

/* Set the value to use for the order month because
   functions are not allowed in the sp_executesql parameter
   list. */
SET @OrderMonth = DATEPART(mm, @PrmOrderDate)

EXEC sp_executesql @InsertString,
     N'@InsOrderID INT, @InsCustID INT, @InsOrdDate DATETIME,
       @InsOrdMonth INT, @InsDelDate DATETIME',
     @PrmOrderID, @PrmCustomerID, @PrmOrderDate,
     @OrderMonth, @PrmDeliveryDate

GO

Using sp_executesql in this procedure is more efficient than using EXECUTE to execute a string. When sp_executesql is used, there are only 12 versions of the INSERT string that are generated, one for each monthly table. With EXECUTE, each INSERT string is unique because the parameter values are different. Although both methods generate the same number of batches, the similarity of the INSERT strings generated by sp_executesql makes it more likely that the query optimizer will reuse execution plans.

C. Using the OUTPUT Parameter

The following example uses an OUTPUT parameter to store the result set generated by the SELECT statement in the @SQLString parameter. Two SELECT statements are then executed that use the value of the OUTPUT parameter.

USE AdventureWorks;
GO
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE @SalesOrderNumber nvarchar(25);
DECLARE @IntVariable int;
SET @SQLString = N'SELECT @SalesOrderOUT = MAX(SalesOrderNumber)
  FROM Sales.SalesOrderHeader
  WHERE CustomerID = @CustomerID';
SET @ParmDefinition = N'@CustomerID int,
                       @SalesOrderOUT nvarchar(25) OUTPUT';
SET @IntVariable = 22276;
EXECUTE sp_executesql
  @SQLString,
  @ParmDefinition,
  @CustomerID = @IntVariable,
  @SalesOrderOUT = @SalesOrderNumber OUTPUT;
-- This SELECT statement returns the value of the OUTPUT parameter.
SELECT @SalesOrderNumber;
-- This SELECT statement uses the value of the OUTPUT parameter in
-- the WHERE clause.
SELECT OrderDate, TotalDue
FROM Sales.SalesOrderHeader
WHERE SalesOrderNumber = @SalesOrderNumber;

Release History
5 December 2005
New content:
  • Added example C.
Changed content:
  • Corrected the OUTPUT parameter syntax.
  • Changed “a variable that can be implicitly converted to ntext” in the definition of stmt and parameter_name to “a Unicode variable.”

Yazı kategorisi: Transact-SQL, sp_executesql | » yorum bırak;

sp_executesql (T-SQL)

Yazan: esersahin 27/04/2009

http://doc.ddart.net/mssql/sql70/sp_ea-ez_4.htm

Executes a Transact-SQL statement or batch that can be reused many times, or that has been built dynamically. The Transact-SQL statement or batch can contain embedded parameters.

Syntax

sp_executesql [@stmt =] stmt
[
{, [@params =] N’@parameter_name  data_type [,...n]}
{, [@param1 =] value1[,...n] }
]

Arguments
[@stmt =] stmt
Is a Unicode string containing a Transact-SQL statement or batch. stmt must be either a Unicode constant or a variable that can be implicitly converted to ntext. More complex Unicode expressions (such as concatenating two strings with the + operator) are not allowed. Character constants are not allowed. If a constant is specified, it must be prefixed with an N. For example, the Unicode constant N’sp_who’ is legal, but the character constant ‘sp_who’ is not. The size of the string is limited only by available database server memory.stmt can contain parameters having the same form as a variable name, for example:

N'SELECT * FROM Employees WHERE EmployeeID = @IDParameter'

Each parameter included in stmt must have a corresponding entry in both the @params parameter definition list and the parameter values list.

[@params =] N’@parameter_name data_type [,...n]
Is one string that contains the definitions of all parameters that have been embedded in stmt. The string must be either a Unicode constant or a variable that can be implicitly converted to ntext. Each parameter definition consists of a parameter name and a data type. n is a placeholder indicating additional parameter definitions. Every parameter specified in stmt must be defined in @params. If the Transact-SQL statement or batch in stmt does not contain parameters, @params is not needed. The default value for this parameter is NULL.
[@param1 =] value1
Is a value for the first parameter defined in the parameter string. The value can be a constant or a variable. There must be a parameter value supplied for every parameter included in stmt. The values are not needed if the Transact-SQL statement or batch in stmt has no parameters.
n
Is a placeholder for the values of additional parameters. Values can be only constants or variables. Values cannot be more complex expressions such as functions, or expressions built using operators.
Return Code Values

0 (success) or 1 (failure)

Result Sets

Returns the result sets from all the SQL statements built into the SQL string.

Remarks

sp_executesql has the same behavior as EXECUTE with regard to batches, the scope of names, and database context. The Transact-SQL statement or batch in the sp_executesql stmt parameter is not compiled until the sp_executesql statement is executed. The contents of stmt are then compiled and executed as an execution plan separate from the execution plan of the batch that called sp_executesql. The sp_executesql batch cannot reference variables declared in the batch calling sp_executesql. Local cursors or variables in the sp_executesql batch are not visible to the batch calling sp_executesql. Changes in database context last only to the end of the sp_executesql statement.

sp_executesql can be used instead of stored procedures to execute a Transact-SQL statement a number of times when the change in parameter values to the statement is the only variation. Because the Transact-SQL statement itself remains constant and only the parameter values change, the Microsoft® SQL Server™ query optimizer is likely to reuse the execution plan it generates for the first execution.


Note If object names in the statement string are not fully qualified, the execution plan is not reused.


sp_executesql supports the setting of parameter values separately from the Transact-SQL string:

DECLARE @IntVariable INT

DECLARE @SQLString NVARCHAR(500)

DECLARE @ParmDefinition NVARCHAR(500)

/* Build the SQL string once.*/

SET @SQLString =

N'SELECT * FROM pubs.dbo.employee WHERE job_lvl = @level'

SET @ParmDefinition = N'@level tinyint'

/* Execute the string with the first parameter value. */

SET @IntVariable = 35

EXECUTE sp_executesql @SQLString, @ParmDefinition,

@level = @IntVariable

/* Execute the same string with the second parameter value. */

SET @IntVariable = 32

EXECUTE sp_executesql @SQLString, @ParmDefinition,

@level = @IntVariable

Being able to substitute parameters in sp_executesql offers these advantages to using the EXECUTE statement to execute a string:

  • Because the actual text of the Transact-SQL statement in the sp_executesql string does not change between executions, the query optimizer will probably match the Transact-SQL statement in the second execution with the execution plan generated for the first execution. Therefore, SQL Server does not have to compile the second statement.
  • The Transact-SQL string is built only once.
  • The integer parameter is specified in its native format. Casting to Unicode is not required.
Permissions

Execute permissions default to the public role.

Examples
A. Execute a simple SELECT statement

This example creates and executes a simple SELECT statement that contains an embedded parameter named @level.

execute sp_executesql

N'select * from pubs.dbo.employee where job_lvl = @level',

N'@level tinyint',

@level = 35

B. Execute a dynamically built string

This example shows using sp_executesql to execute a dynamically built string. The example stored procedure is used to insert data into a set of tables used to partition sales data for a year. There is one table for each month of the year with the following format:

CREATE TABLE May1998Sales

(OrderID        INT        PRIMARY KEY,

CustomerID        INT        NOT NULL,

OrderDate        DATETIME    NULL

CHECK (DATEPART(yy, OrderDate) = 1998),

OrderMonth        INT

CHECK (OrderMonth = 5),

DeliveryDate    DATETIME    NULL,

CHECK (DATEPART(mm, OrderDate) = OrderMonth)

)

For more information about retrieving data from these partitioned tables, see Using Views with Partitioned Data.

The name of each table consists of the first three letters of the month name, the four digits of the year, and the constant Sales. The name can be built dynamically from an order date:

/* Get the first three characters of the month name. */

SUBSTRING( DATENAME(mm, @PrmOrderDate), 1, 3) +

/* Concatenate the four-digit year; cast as character. */

CAST(DATEPART(yy, @PrmOrderDate) AS CHAR(4) ) +

/* Concatenate the constant 'Sales'. */

'Sales'

This sample stored procedure dynamically builds and executes an INSERT statement to insert new orders into the correct table. It uses the order date to build the name of the table that should contain the data, then incorporates that name into an INSERT statement. (This is a simple example for sp_executesql. It does not contain error checking and does not include checks for business rules, such as ensuring that order numbers are not duplicated between tables.)

CREATE PROCEDURE InsertSales @PrmOrderID INT, @PrmCustomerID INT,

@PrmOrderDate DATETIME, @PrmDeliveryDate DATETIME

AS

DECLARE @InsertString NVARCHAR(500)

DECLARE @OrderMonth INT

-- Build the INSERT statement.

SET @InsertString = 'INSERT INTO ' +

/* Build the name of the table. */

SUBSTRING( DATENAME(mm, @PrmOrderDate), 1, 3) +

CAST(DATEPART(yy, @PrmOrderDate) AS CHAR(4) ) +

'Sales' +

/* Build a VALUES clause. */

' VALUES (@InsOrderID, @InsCustID, @InsOrdDate,' +

' @InsOrdMonth, @InsDelDate)'

/* Set the value to use for the order month because

functions are not allowed in the sp_executesql parameter

list. */

SET @OrderMonth = DATEPART(mm, @PrmOrderDate)

EXEC sp_executesql @InsertString,

N'@InsOrderID INT, @InsCustID INT, @InsOrdDate DATETIME,

@InsOrdMonth INT, @InsDelDate DATETIME',

@PrmOrderID, @PrmCustomerID, @PrmOrderDate,

@OrderMonth, @PrmDeliveryDate

GO

Using sp_executesql in this procedure is more efficient than using EXECUTE to execute a string. When sp_executesql is used, there are only 12 versions of the INSERT string generated, 1 for each monthly table. With EXECUTE, each INSERT string is unique because the parameter values are different. Although both methods generate the same number of batches, the similarity of the INSERT strings generated by sp_executesql makes it more likely that the query optimizer will reuse execution plans.

See Also
Batches EXECUTE
Building Statements at Run Time System Stored Procedures

(c) 1988-98 Microsoft Corporation. All Rights Reserved.

Yazı kategorisi: Transact-SQL, sp_executesql | » yorum bırak;

Python v2.6.2 documentation

Yazan: esersahin 26/04/2009

http://www.python.org/doc/current/

Welcome! This is the documentation for Python 2.6.2, last updated Apr 26, 2009.

Parts of the documentation:

Indices and tables:

Meta information:

Yazı kategorisi: Phyton | » yorum bırak;

Python recipes

Yazan: esersahin 26/04/2009

http://code.activestate.com/recipes/langs/python/

Yazı kategorisi: Phyton | » yorum bırak;

Dive Into Python

Yazan: esersahin 26/04/2009

http://diveintopython.org/

Dive Into Python is a Python book for experienced programmers. You can buy a printed copy, read it online, or download it in a variety of formats. It is also available in multiple languages.

Yazı kategorisi: Phyton | » yorum bırak;

Pydev Extensions

Yazan: esersahin 26/04/2009

http://www.fabioz.com/pydev/download.html

Yazı kategorisi: Eclipse, Phyton | » yorum bırak;

Source Control for Visual Studio 2008: VisualSVN Server, TortoiseSVN, & AnkhSVN – Part I

Yazan: esersahin 26/04/2009

http://www.codeproject.com/KB/dotnet/VistaVisualSourceControl.aspx

Introduction

Though I’ve been programming computers as a hobby since 1980, most of this was done on single machines by myself. Needless to say, I’ve lost work due to hardware failures, inadvertent deletion, and just plain “breaking” my working code. Ultimately, this created too much extra work and sweat.

In this article I’ll describe how to transition from simply saving your code in folders on your computer, to using a revision control system which should safeguard your code and allow code “tinkering” without destructive or irreversible consequences.

Background

While there are many articles about how to set up and use a source code control system, I found many were limited, dated, or uncompleted; or they dealt with a much larger team approach to coding. This article attempts to translate my lengthy research among this mire into a helpful article suited to those entering the year 2009.

Getting Started

For the purposes of this article, I’ll assume the following:

  • You are NOT independently wealthy (you do not have the capitol to invest in enterprise development solutions).
  • You already have Visual Studio 2008 (not Express) installed and running on your Vista machine. (Where all your hard earned cash has been invested)
  • You already have personal code you work with using VS2008 and are storing it on your computer. Perhaps some source code you found online and have modified.

Slide1.JPG

The tools used for this project are:

  • VisualSVN Server – SVN web server to handle requests across HTTP connections
  • TortoiseSVN – Windows Explorer context-menu based SVN utility
  • AnkhSVN – VS2008 SVN add-in utility

There are many alternatives to these tools. In fact, all three duplicate the majority of each other’s SVN functions since all include “Subversion”. I’ve chosen them for no particular reason, though all are freely available, seem to be in growing use, and support current software versions. I’d recommend going ahead and downloading a recent copy of each to be installed using the guidance below.

For the purposes of this article I’m using:

  • VisualSVN Server v1.6.2
  • TortoiseSVN v1.5.5, Build 14361
  • AnkhSVN v2.0..5250.202

(Note: if you follow the pictures too closely, you’ll notice my server name is “Dad”, my Vista installation is on my I:/ drive using my H:/ drive for storage, and the project I’m using is the SourceOutliner powertoy available at CodePlex.com)

SVN Source Control Concepts

Before we begin, it’s helpful to understand what we’ll be doing and why we’re doing it. Here’s where my biggest struggle began. Perhaps you’ve already interacted with CVS or even SVN code repositories online at places such as SourceForge.net. But if you are like me, you didn’t go any deeper than “checking out” code to download it to your computer and fiddle with it.

Slide2.JPG

Though not the best example, a code repository is like the old “Briefcase” file on the Windows95 desktop (did anyone ever really use it?) The code repository is a storehouse containing the code files and all modifications to those code files, along with who modified them and their comments. Subversion (SVN) programs perform the interaction and record-keeping. Specifically, there are no folders or files within the repository when viewed using the file system. However when using a Subversion program, it accesses the repository and displays the database as if it were a file system.

Slide3.JPG

The code repository is simply a database filled with records. It can be acted on via the local file system or remotely via HTTP. Therefore, an SVN Server is a web server that handles interaction with the code repository across HTTP and uses its built-in Subversion to track all changes. It also acts as a database server in that respect since it regulates tracking of revisions. The SVN Server is a portal through which all code file changes go in and out of the code repository.

Slide4.JPG

And finally, TortoiseSVN and AnkhSVN are graphical interface utilities which contain Subversion and also allow interaction with an SVN Server instead of using command-line utilities. While TortiseSVN is integrated into the Vista file system (namely the Windows Explorer), AnkhSVN is integrated inside VS2008.

Slide5.JPG

(Sidebar discussion: To reach the results of this project, the SVN server is not really needed, nor is TortoiseSVN once we create a repository with one of them. However, my goal is to acquaint us with how SVN works across the internet using remote servers. It just so happens for our project, our local and remote workstations are one and the same. Generally, every place we access the SVN server using https:// we could just as easily use file:/// and access a local repository on our computer or the Windows network.)

Setting Up the VisualSVN Server

First we’ll make plans to install the VisualSVN Server on our Vista machine, then we’ll install it.

I keep my personal source code stored in the default VS2008 “projects’ folder found at “C:\My Documents\Visual Studio 2008\Projects.” This is not going to change.

Next we must choose where we’ll host our code repository. Though I’m breaking rules by keeping all this on the same computer, I’d at least recommend your keeping the repository on a separate partition or separate hard drive. (Even better yet, on a separate Win32 box using it as a file server, but that’s beyond the scope of this project). We’ll use “D:\SVNRepository”

Then we must choose what type of security we’ll use, it has two parts. Since the SVN Server is a web server, the first part we must decide is if we want a secure connection to the svn server (https://) including how to avoid conflicting with an existing IIS7 web server. We’ll go with a default secure connection using the default settings which can be changed later. For the second part we must decide how users authenticate with the server. We’ll choose windows authentication since its better integrated.

Now’s the time to install the VisualSVN Server using the details decided above.

VisualSVN-Setup.jpg

When the installation is complete, you should have the VisualSVN Server Manager displayed. Before we can actually access this server, we’ll first need to add some users. Right-click on the “Repositories” item in the left pane and select “Properties.” Add our user name with read/write permission. We also might want to add “Guest” read only permission.

VisualSVN-Users1.jpg

Next we’ll create a code repository which is a folder inside our main repository. In our case, we’ll use a single repository to store all our projects by a project name folder. We can always add or reorganize later. We can either right-click on the “Repositories” item in the left pane and select “Create new repository…” or choose that item if it’s displayed in the main right pane. We’ll name our repository “Main” and there’s no need to create a default structure at this root level, we’ll do that inside each of our projects (my layout preference)

VisualSVN-Repository.jpg

If everything has gone well, at this point we can see our SVN repository. We can right-click on the “Repositories” or “Main” items in the left pane and select “Browse” or click on the Server URL if it’s displayed in the main right pane.

VisualSVN-Repository1.jpg

For now, we’ve completed setting up the VisualSVN Server.

Setting Up TortoiseSVN and AnkhSVN

At this point we’ll install our two graphical interface utilities. Try not to worry about the “Vista” warning when installing TortoiseSVN and just do it.

Next we’ll check to see if AnkhSVN is set to work with VS2008. Launch VS2008 and select “Tools”, “Options” then the “Source Control” settings. The Current source control plug-in should be AnkhSVN. If not, drop-down the list and select it. Again, if you’re a fan of WinMerge, you could set it up under Source Control-Subversion. Well stick with the default AnkhSVN utilities.

AnkhSVN-Setup.jpg

Importing your code into your repository

So, if we’ve been successful at following up to this point, we have a running SVN server, a remotely accessible local repository, and a VS2008 interface. However our personal source code is still just sitting in our projects folder awaiting destruction from hardware failure or undisciplined code changes.

This next concept was the second biggest hurdle for me to overcome. Thankfully AnkhSVN automates most of the lengthy steps you’d find elsewhere on the web. We will continue to work with our code from the same location as we always have. However, we will begin using the SVN repository as a backup and revision management facility.

Inside VS2008, open our source code project as always. Next, in the Solution Explorer, right-click on the solution name select “Add Solution to subversion…” We’ll need to use an SVN server path which includes the repository name. In my case it’s https://dad:8443/svn/Main. Anything less, and it won’t find the server. Select “svn/Main”, and check off “Add trunk Folder for project”. Refrain from creating a new folder or selecting a project already within the repository unless this is a subproject. After clicking “OK” we’ll be asked for a log message, I’d suggest “Initial import into repository.” We’ve successfully preped the project for inclusion into the repository. Note a slew of icon glyphs (yellow and blue plus signs) have been added inside the Solution Explorer.

VS2008-Add.jpg

Although the VS2008 “solution” is connected to the repository, the VS2008 “projects” inside the solution are not. In the Solution Explorer, right-click on the solution name select “Add Selected Projects to subversion…” We can connect or disconnect the solution or projects from subversion using the “File”, “Subversion”, “Change Source Control” menu item.

Now wait! You’d think we were done at this point…however, we’re only halfway to actually adding our project to the repository. Go ahead and browse the repository. Our new project is NOT there. We’ve turned on source control features within our VS2008 project, but not committed it to the repository. This is actually a “feature” not an added step. What we do inside VS2008 doesn’t have to affect our repository. Go ahead and exit VS2008 saving your work. As a learning point, this is what we’ll be doing in the future. That is, modifying our “working copy” as we’ve always done. We’re not required to update the repository with EVERY minor change. Restrain yourself if necessary!

Go ahead and re-launch VS2008 and open our project. Everything is as we left it! To import our work into the repository, we must “commit” it. Open the “Pending Changes” window at the bottom. You’ll see the list of “changes” not yet acted on. Also notice the “Commit” and “Update” buttons at the top left of that window. These will become our most used SVN friends in due time.

  • “Commit” adds changes we’ve made to our working copy into the repository as a new revision
  • “Update” attempts to update our working copy to the latest version in the repository

VS2008-Commit.jpg

We’ll deal with possible conflicts between our working copy and the repository in another article. For now, we know our project is not yet in the newly created repository, so click the “Commit” button to import it there. Notice all the files listed in the pending window disappeared and the “Commit” and “Update” buttons are no longer enabled. Congratulations, our working project is in sync with the repository. Verify this by browsing your repository. We may have to refresh the page or management console to get it to display the updates. If we browse our project’s working folder in Windows Explorer, we should notice the files and folders now have glyphs similar to what’s inside VS2008 thanks to TortoiseSVN. We’ll also notice “_svn” folders containing our local source code control information.

Conclusion

We’ve gotten SVN up and running locally and learned how to adapt VS2008 projects to SVN source control. In part II, we’ll learn how to work with changes to our source code and how the repository can be our friend.

In summary in this article we:

  • We installed an SVN server and utilities
  • We created a local SVN repository which can be accessed remotely
  • We added Source Control features to a programming project and then added it to our SVN repository

Tweaking your setup

Since VisualSVN Server is a graphical interface to a Win32 version of the Apache web server, we can easily modify the configuration.

To tweak the SVN browser display and allow easy interaction with TortiseSVN and Windows Explorer, see this article: Customise VisualSVN Server browser view On your Vista machine you will need to install the WebFolders feature and set up a “Network Place”.

Credits and References

Here’s some additonal references to better understand and use SVN.

History

  • Nov 24, 2008 – Removed note to change TortoiseSVN setting since it only applies to VS.Net 2003.
  • Nov 22, 2008 – Began working on my first article for CodeProject. it may need corrections to add additional steps when installing on a clean machine.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

Dave Leffler

Yazı kategorisi: Subversion, VisualSVN | » yorum bırak;

Subclipse

Yazan: esersahin 26/04/2009

http://subclipse.tigris.org/

Subclipse is an Eclipse Team Provider plug-in providing support for Subversion within the Eclipse IDE. The software is released under the Eclipse Public License (EPL) 1.0 open source license.

Subversion 1.6.0 Support

Subclipse 1.6.x releases are now available and includes support for Subversion 1.6.0 features including tree conflicts.

Revision Graphs!

Subclipse 1.4.x release now includes an optional revision graph feature! Click here to read more.

Revision graph

View all project announcements including RSS feed.

Other Projects

In addition to Subclipse, there are two other projects hosted on this site:

Get the right version!

Subclipse versions are tied to specific versions of the Subversion client API.  So you must have a matching version of the Subversion client API (JavaHL) for your version of Subclipse.  Any 1.x version of a Subversion client can talk to any 1.x version of a Subversion server, so generally the version does not matter too much.  However, if you use multiple client tools on the same Subversion working copy, then it is important that the version of those clients is all the same.  In addition, if you are on Linux, your distribution might only support a specific version of Subversion and JavaHL.  So you might want to stick with a specific version of Subclipse for that client.

More information on how to get JavaHL, and the right version for each version of Subclipse can be found in the wiki .

Current Release

Eclipse 3.2/Callisto, 3.3/Europa, 3.4/Ganymede +

Subclipse 1.6.2 and 1.4.8 are now available for Eclipse 3.2+!

See the changelog for details. Existing Subclipse users should read the upgrade instructions for important information on changes you to need to make to your Eclipse preferences to see the new version in the update manager.

Subclipse 1.4.x includes and requires Subversion 1.5.x client features and working copy format.

Subclipse 1.6.x includes and requires Subversion 1.6.x client features and working copy format.

Links for 1.6.x Release:
Changelog: http://subclipse.tigris.org/subclipse_1.6.x/changes.html
Eclipse update site URL: http://subclipse.tigris.org/update_1.6.x
Zipped downloads: http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240

Links for 1.4.x Release:
Changelog: http://subclipse.tigris.org/subclipse_1.4.x/changes.html
Eclipse update site URL: http://subclipse.tigris.org/update_1.4.x
Zipped downloads: http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240

Eclipse 3.0/3.1

Subclipse 1.0.6 is now available for Eclipse 3.0/3.1!

See the changelog for details. Existing Subclipse users should read the 1.0.0 release announcement for details on how to upgrade to the 1.0.x release.

Links for 1.0.x Release:
Changelog: http://subclipse.tigris.org/subclipse/changes.html
Eclipse update site URL: http://subclipse.tigris.org/update_1.0.x
Zipped downloads: http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240

Eclipse 2.1.3

Subclipse 0.9.3.3 is linked against Subversion 1.1.4. Binaries for Windows are included.

Development for this version of Eclipse is no longer active. There are no new releases planned.

Download the Eclipse 2.x version

Installation Instructions

Here you will find a screenshot tour of the Subclipse installation process in Eclipse 3.x. These particular screens were captured in Eclipse 3.0.2 running on Windows XP.

Install Subclipse in Eclipse 3.x

Step 1:

Begin the installation from the Eclipse Help menu item.

Install screenStep 2:

This screenshot show the screen as it initially comes up. In this case you will need to change the radio button to indicate that this is a new install.

Install screenStep 3:

This screen will vary depending on the features you have installed already. You want to click on the New Remote Site button. If you are behind a proxy and the Eclipse install mechanism does not work, then you can download a zipped version of the update site and then click the New Local Site button instead.

Install screenStep 4:

This screen is showing the New Remote Site dialog, filled in with the correct information to install Subclipse

              Name: Subclipse 1.6.x (Eclipse 3.2+)
              URL:  http://subclipse.tigris.org/update_1.6.x
              Name: Subclipse 1.4.x (Eclipse 3.2+)
              URL:  http://subclipse.tigris.org/update_1.4.x
              Name: Subclipse 1.2.x (Eclipse 3.2+)
              URL:  http://subclipse.tigris.org/update_1.2.x
              Name: Subclipse 1.0.x (Eclipse 3.0/3.1)
              URL:  http://subclipse.tigris.org/update_1.0.x

Install screenStep 5:

When you first come back to this screen, the site you added will NOT be selected. Be sure to select it before clicking Next.

Install screenStep 6:

This next screen shows all of the features that are available to install.

Install screenStep 7:

Click the button to accept the license agreement.

Install screenStep 8:

Confirm the install location

Install screenStep 9:

There is an Eclipse preference to turn off this next dialog. I have never seen a signed feature. Not even Eclipse.org nor IBM sign their features.

Install screenStep 10:

Just a screenshot of the in-process installation.

Install screenStep 11:

Eclipse needs to be restarted after installing Subclipse.

Install screenStep 12:

Finally, after restarting Eclipse, the first thing you will typically want to do is open the Subclipse Repository perspective where you can define your repositories. Be sure to also check the online help as well as the Subclipse preferences located under Team -> SVN.

Install screen

Updating Subclipse in Eclipse 3.x

Eclipse 3.x has a feature in preference to automatically check for updates. Provided you are not behind a proxy that does not allow this feature, it should work for Subclipse. Otherwise just follow the instructions for installing Subclipse, except take the option to check for updates in Step 2.

If you are behind a proxy that does not work with Eclipse, then to install updates you just always follow the same instructions you used to install a new version. If you always unzip the site to the same local folder, you will not have to define the local site each time.

Yazı kategorisi: Eclipse, Subclipse | » yorum bırak;

How to use Subversion with Eclipse

Yazan: esersahin 26/04/2009

http://www.ibm.com/developerworks/opensource/library/os-ecl-subversion/

Level: Intermediate

Chris Herborth (chrish@pobox.com), Freelance Writer, Author

11 Jul 2006

From the beginning, Eclipse included tight integration with the Concurrent Versions System (CVS) in order to provide access to change-management capabilities. Now, many projects — notably those run by the Apache Software Foundation — are using a different change-management system: Subversion. Find out how to use Eclipse for projects that use a Subversion repository.


// <![CDATA[
capture_referrer();
// ]]>

A stock Eclipse installation has integrated support for CVS, a popular open source change-management system. The abilities of CVS, and its limitations, are well known, but many groups have been investigating other version-control systems to provide better scaling, better support for merging changes and branching versions, and better support for binary file formats.

Subversion (SVN) is a popular replacement for CVS, offering improved performance (courtesy of intelligent local caching and a database back end), easy and fast branching, and an answer to every one of the shortcomings that people often run into while using CVS.

Read on to see how to add Subversion support to Eclipse and how to perform basic version-control activities from the IDE.

Before you start

You’re going to need to download and install Eclipse (see Resources) to follow along. Downloading the Eclipse SDK package for your platform will give you the base Eclipse IDE (referred to as the Eclipse Platform), as well as the Java™ Development Kit. If you plan on working with C/C++ (as I tend to), visit the C Development Tooling (CDT) Web site and install the CDT using the update manager (using the update manager is described in the next section).

You’ll also need access to a Subversion repository. If you need to set one up, you can find excellent documentation at the Subversion Web site (see Resources). For demonstration purposes, I’ll show you how to check out the Subclipse project and work with projects in a repository on my LAN.

Back to top

Adding Subclipse to Eclipse

Subclipse is a project to add Subversion support to the Eclipse IDE. We’ll use Eclipse’s update manager to add Subclipse to our Eclipse IDE. From the Help menu in Eclipse, choose Software Updates > Find and Install to open the update manager.
Figure 1. The Eclipse update manager
Eclipse update manager

In addition to using this to look for software updates, we can use the update manager to find and install new features, such as Subclipse. Be sure that Search for new features to install is selected, then click Next to continue. Eclipse displays the next update manager panel.
Figure 2. Update manager sites
Update manager sites

Since we’re after a specific feature, un-check the existing sites, then click New Remote Site to display the New Update Site dialog (see Figure 3). We’ll use this to add the Subclipse update site to the list.
Figure 3. Adding a new update site
Adding a new update site

Enter whatever you want for the Name (Subclipse is a good choice) and enter the following for the URL: http://subclipse.tigris.org/update_1.0.x (the current Subclipse update site). Click OK to add the Subclipse update site to the list in the update manager.

Click Finish in the update manager window to begin searching for new features. In this case, the new feature we’re after is Subclipse. After a few moments, the update manager’s search is complete, and it displays the search results.
Figure 4. New features we can install
New features we can install

Check Subclipse (you can click the disclosure triangle to see what exactly is included in this feature), then click Next to view the feature’s license terms. Accept the terms, then click Next to review the features you’ve chosen to install. Click Finish to download and install Subclipse.

The update manager downloads the Subversion components. Before installing anything, Eclipse will warn you that the features aren’t digitally signed (Figure 5). This is your last chance to cancel the installation. Click Install All to continue the installation.
Figure 5. Subclipse isn’t digitally signed
Subclipse isn't digitally signed

Once Subversion has been installed, Eclipse warns you that you might need to restart the IDE to activate the new features (see Figure 6). Restart Eclipse, just in case.
Figure 6. Restart Eclipse after installing new features
Restart Eclipse after installing new features

When Eclipse comes back up, Subclipse is installed and ready to go.

If you’re running Eclipse on Mac OS X or Linux®, you may need to install the JavaHL library, which is described in the Troubleshooting section of the Subclipse FAQ (see Resources). Do this before you continue trying to use Subclipse.

A quick test

It’s always nice to test a new feature once you’ve finished the installation; we’ll try checking out a copy of Subclipse from their Subversion repository to make sure it’s been properly installed.

From Eclipse’s File menu, choose Import to display the import manager (see Figure 7). Choose Checkout Projects from SVN, then click Next.
Figure 7. The import manager
The import manager

On the Select/Create Location panel (see Figure 8), we need to create a new location (since we don’t have any configured yet), so click Next to continue. If the Next button is disabled, switch to the Use existing repository location option, then back to Create a new repository location to enable the Next button.
Figure 8. Creating a new repository location
Creating a new repository location

In the next section (see Figure 9), add the repository URL (http://subclipse.tigris.org/svn/subclipse/) to the Url field, then click Next. After a moment, Eclipse prompts you for user ID and password. If you don’t have an account on the Subclipse site, enter guest for the user ID and a space for the password, check the Save Password box, and click OK.
Figure 9. Add the repository URL
Add the repository URL

Eclipse displays the folders in the Subclipse repository (see Figure 10). Expand the trunk and choose the subclipse folder, then click Finish to check out your own copy of the Subclipse project’s source code. Since you have no idea what this is, choose Simple > Project when the New Project wizard prompts you.
Figure 10. Subclipse repository
Subclipse repository

Back to top

Basic Subversion operations

At this point, we’ve installed Subclipse successfully, which added support for Subversion servers to our Eclipse setup, and we’ve tested Subclipse by downloading the current Subclipse source code from the repository. Now we should look at doing something with our own code and our own Subversion repository.

Before I show you how things work with Subversion, I’ll tell you a little bit about my repository. It’s hosted on a machine called dogma on port 8000, and I’ve created a new developerworks repository for code associated with my developerWorks articles. I’m going to put my projects directly in the root of the repository. Other repositories often have folders named trunk, tags, and branches off the root, for development versions, tags, and branches, but I don’t expect to need to worry about tagging or branching the developerWorks article code.

I’ve added two projects, forkWork and threadWork, from my first developerWorks article. My Eclipse workspace (see Figure 11) also contains three other projects from developerWorks articles (getopt_demo, getopt_long_demo, and readdir_demo).
Figure 11. My Eclipse C/C++ projects
My Eclipse C/C++ projects

Now we’re ready to get to work.

Adding a project to the repository

To add a new project to your Subversion repository, right-click the project (in any of Eclipse’s project views or the Navigator view) and choose Team > Share Project from the menu. Eclipse displays the Share Project dialog.
Figure 12. The Share Project dialog
The Share Project dialog

Select SVN from the list of repositories currently supported by your Eclipse, then click Next. The next dialog (see Figure 13) lets you choose an existing repository location, or you can create a new one.
Figure 13. Selecting a repository location
Selecting a repository location

If your repository is already listed (as you can see, I’ve added mine), select it, and click Finish. If your repository isn’t listed, add it (see A quick test for instructions) and continue. Eclipse creates a new directory in the repository with the same name as your project, and displays a list of all files and folders in the project.
Figure 14. Adding a project’s contents
Adding a project's contents

Enter a suitable comment describing this project in the top field, then click Select All to check all of the files from the project. Click OK to check in your project and transmit its current state to the Subversion repository.

Subversion’s commands and output are displayed in the Console view, usually found at the bottom of your Eclipse window, if you want to see exactly what Subclipse did with your project.

Updating a project

One of the key features of a version-control system is the ability for other developers to continue development and commit their changes whenever they’re ready. To download these changes and integrate them with your local copies, you need to update the project.

Right-click on the project you want to update, then choose Team > Update from the menu. Eclipse retrieves any changes from the repository and attempts to merge them with your local copy.

Adding a file or directory

If you add a file to your project (see Figure 15), it’s not automatically part of version control — you need to specifically add it to the repository. In the screenshot, you can see that I’ve added a ReadMe.txt file to the threadWork project.
Figure 15. Adding a new file
Adding a new file

Right-click the new file, then choose Team > Add to Version Control. That’s it! The next time you commit your changes in this project to the repository, the new file will also be checked in.

Deleting a file or directory

If you’ve added a file to the repository that’s no longer relevant to your project, you can easily delete it. Right-click the file, then choose Delete. No need for the Team menu, Subclipse flags the file for deletion automatically and removes it from your project. The next time you commit your changes to the repository, the file is deleted.

Renaming a file or directory

To rename a file or directory under Subclipse’s control, right-click it, then choose Rename. Type the item’s new name in the entry field and click Enter. The file is renamed in the project, and the rename operation (an Add for the new name, and a Delete for the old one) is queued for your next commit. In Figure 16 you can see the threadWork project after I’ve renamed main.c to threadWork.c, but before I’ve committed my change. Note the little blue plus sign Subclipse has added to the “new” file to indicate that it’s scheduled for addition in the next commit.
Figure 16. Renaming a file is atomic, even though it’s an add and a delete
Renaming a file is atomic, even though it's an add and a delete

Ignoring files

If your project generates files, or otherwise includes files that you don’t want to check in to the Subversion repository, you can tell Subclipse to ignore them. Right-click the file or directory you want to exclude from version control, then choose Team > Add to svn:ignore to display the Add to svn:ignore dialog.
Figure 17. Ignoring resources that don’t belong in version control
Ignoring resources that don't belong in version control

Click OK to add this specific file to the svn:ignore property for the project’s directory. Choose Wildcard extension to ignore all files with the current file’s extension, or choose Custom pattern to add your own wild card to the ignore list. These changes to the ignore list will be added to the repository the next time you commit your changes.

Committing your changes

Once you’re happy with your changes to the project, you’ve made sure your code compiles, and you’ve tested your changes, you should commit them to the Subversion repository. This acts as a backup in case your workstation self-destructs, and it lets other developers update their local copies to include your changes.

Be sure to update your project (see “Updating a project”) before attempting to commit your changes. Right-click the project and choose Team > Commit from the menu. Eclipse displays the Commit dialog (see Figure 18), which summarizes your changes.
Figure 18. Committing your changes to the repository
Committing your changes to the repository

If you look carefully, you’ll see a property change to the project’s directory (I’ve added to the svn:ignore property to keep certain files out of the repository) and that main.c was deleted while threadWork.c was added. That pair of changes actually represents one operation (a file rename).

At this point, you can deselect resources if you want to keep them out of the repository. This might be helpful if you’re partially finished work in one file, and don’t want to check in an incomplete change. Enter a suitable comment in the top text field, then click OK to check in your changes to the repository.

Back to top

Summary

The Subclipse project integrates support for the Subversion version-control system with Eclipse’s excellent team project management features, which only support CVS servers out of the box. Using Eclipse’s update manager, it’s easy to add Subclipse to your Eclipse installation, which lets you use this superior (in my opinion, at least) version-control system directly from Eclipse.

While adding projects to a repository — and managing your project’s resources once it’s there — can be daunting for folks unfamiliar with Subversion, the procedures for common operations are straightforward. This article walked you through the everyday operations to help familiarize you with Subclipse.

Resources

Learn

Get products and technologies

Discuss

Yazı kategorisi: Eclipse, Subversion | » yorum bırak;