View on GitHub

Bearded-android-docs

MigratingFromJava2

Download this project as a .zip file Download this project as a tar.gz file

Created Wednesday 08 January 2014

Anonymous Types

You create anonymous types by using the new operator together with an object initializer:

var anonymousType = new { First = "Uriel", Last = "Avalos" }; 
Console.WriteLine(v.Amount + v.Message);

Extension Methods

An extension method "adds" new methods to existing types without modifying the original source code. In most cases, you will be using pre-defined extension methods instead of creating your own.

Limitations

Creating an Extension Method

using System.Linq;
using System.Text;
using System;

namespace CustomExtensions
{
    //Extension methods must be defined in a static class 
    public static class StringExtension
    {
        // This is the extension method. 
        // The first parameter takes the "this" modifier
        // and specifies the type for which the method is defined. 
        public static int MyLength(this String str)
        {
            return str.Length;
        }
    }
}
namespace Extension_Methods_Simple
{
    //Import the extension method namespace. 
    using CustomExtensions;
    class Program
    {
        static void Main(string[] args)
        {
            string s = "The quick brown fox jumped over the lazy dog.";
            //  Call the method as if it were an  
            //  instance method on the type. Note that the first 
            //  parameter is not specified by the calling code. 
            int i = s.MyLength();
        }
    }
}

Delegates

A delegate is a function pointer. Unlike function pointers in C or C++, delegates are object-oriented, type-safe, and secure.

Creating a Delegate


//declare delegate
delegate void foobar(int i);

class Foo
{
    //assign these two as delegates implementing foobar
    public void delegate1(int i) { //... }
    public void delegate2(int i) { //... }
    
    //pass delegate as function pointer to method
    public callDelegate(foobar delegateMethod)
    {
        //call delegate with input 0
        delegateMethod(0);
    }
}

Foo foo = new Foo();

//create delegates
foobar delegate1 = new foobar(foo.delegate1);
foobar delegate2 = new foobar(foo.delegate2);

//invoke delegates directly
delegate1(1000);

//pass delegate to fuction
foo.callDelegate(delegate1);

//NOTE: you can also do chain delegates together!
foobar delegate3 = delegate1 + delegate2;

//calls delegate1 followed by delegate2
delegate3(100);

Delegates vs Interfaces

With the exception of the neat function chaining shown above, you can get the same functionality by using an interface. In fact, in Java, that's the technique that's used to get function-pointer-like behavior. For example:

//declare interface to use as "function pointer"
interface IFunctionPtr { void method(); }

//function to use as "function pointer"
public void functionPtr() { //... }

//accepts "function pointer" as param
public void callFunctionPtr(IFunctionPtr ptr)
{
    //call "function pointer" interface
    ptr.method();
}

//create "function pointer"
IFunctionPtr javaFunctionPtr = new IFunctionPtr() {
    @Override
    public void method() { functionPtr(); }
};

//invoke "function pointer" directly
javaFunctionPtr.method();

//pass "function pointer" to function
callFunctionPtr(javaFunctionPtr);

Unfortunately, other than the neat function chaining described earlier, I don't see any reason to use a delegate except to get more compact code (you don't have to wrap the method with an anonymous class).

Note that there are times when it does not make sense to use a delegate:

Inheritance

In Java, methods are virtual by default. You make them non-virtual with the final keyword. In C#, methods are not virtual by default. You must explicitly make them virtual with the virtual keyword. (See the override/virtual keywords in :CSharp:MigratingFromJava1.)

An explanation via code:

class Base
{
    public void method1() { //... }
}

Base base = new Base();
Derived derived = new Derived(); //extends base
Base bd = new Derived();

|                   | Java                  | C#                    |
|-------------------|-----------------------|-----------------------|
| base.method1()    | calls Base#method1    | calls Base#method1    |
| derived.method1() | calls Derived#method1 | calls Derived#method1 |
| bd.method1()      | calls Derived#method1 | calls Base#method1    |

//in Java, by default, polymorphism (which is slow) kicks in
//in C#, you must explicitly enable polymorphism

Events

C# has built-in support for events.

Creating and Using Events

//Define delegate callback
public delegate boolean ChangedEventHandler(object sender, int i);

class EventClass
{
    //clients register listener with this event
    public event ChangeEventHandler changedEvent;

    public void foo()
    {
        //invoke event
        if (changedEvent != null) 
        {
           if (changedEvent(this, 50)) //...;
           else //....;
    }
}   
	
class Test
{
    //onChange handler
    private boolean onChanged(object sender, int i) { //... }
  
    public void bar()
    {
         EventClass eventClass = new EventClass();
         
         //register event handler
         //"+=" notation means you can add multiple handlers
         eventClass.changedEvent += new ChangedEventHandler(onChanged);

         eventClass.foo(); //calls Test#onChanged

         //unregister event handler

eventClass.changedEvent -= new ChangedEventHandler(onChanged);
}
}

Note: C# provides a built-in delegate for handling events EventHandler which is defined as

public delegate void EventHandler(object sender, EventArgs e);

where EventArgs is a built-in class.

Events and Inheritance


Working with EventHandler Class, Creating Events That Work With .NET Framework

See How to: Publish Events that Conform to .NET Framework Guidelines

Lambdas

A lambda expression are anonymous functions that can be used to create delegates or expression trees.

Creating a Lambda

//first define a delegate
delegate int foo(int i);
delegate int bar(int a, int b);
delegate int foobar();
//...
//these are all equivalent:
foo lambda1 = (x) => x * x;
foo lambda2 = x => x * x;
foo lambda3 = (int x) => x * x;
foo lambda4 = x => { Console.WriteLine(x); return x * x; }; //multi-statement
//multi-params:
bar lambda1b = (x,y) => x + y;
bar lambda2b = (int x, int y) => x + y;
//no params:
foobar lambda1c = () => 4; //returns 4 (DOH!)
//in general,
//(input params) => expression (returning a value)

Note 1: You don't need to specify the type of the input params (like in the examples above). However, the arguments must implicitly cast to the types defined in the delegate.

Note 2: Multi-statement lambdas are called statement lambdas and they are not supported by LINQ expression providers.

Lambdas and Closure

Like Javascript, you can reference outside variables inside of a lambda expression (thereby, creating a closure). And like Javascript, the same issues related to closure apply. For example:

delegate int foo();
foo[] foos = new foo[5];
for (int i=0; i<5; i++) {
    foos[i] = x => i;
}
//does NOT print 0,1,2,3,4
//instead prints 5,5,5,5,5
for (int i=0; i<5; i++)
   Console.WriteLine(foos[i]());

Anonymous Methods vs Lambdas

C# 2.0 introduced anynymous methods and C# 3.0 introduced lambdas. As per the offical docs, lambdas are the preffered way to write inline code.

Creating an Anonymous Method

// Create a delegate. 
delegate void foo(int x);

// create the anonymous method
foo d = delegate(int k) { // ...  };

Unsafe Mode

Unsafe mode is for allowing C/C++ style pointer manipulation. The following are the recommended reasons for using unsafe mode:

Note: With pointers you get better performance than the usual array access; however, the resulting code is harder to maintain. Do NOT use unsafe mode just to write C/C++ code in C#!

See the resources below for more information.

Resources


Backlinks:

NETFramework:CSharp:Delegates NETFramework:CSharp:MigratingFromJava:MigratingFromJava1
comments powered by Disqus