Aug 7, 2015

Overload resolution in C#

After a long dark period of silence I am back :)

This time a little quiz.

Given the following C# program, what you expect to get printed?

using static System.Console;

class Foo 
{ 
 public void Bar(string[] o) { WriteLine("string[]"); } 
 public void Bar(object o) { WriteLine("object"); } 

 static void Main()
 {
  var foo = new Foo();
  foo.Bar(null); 
 } 
}

Answers (if any), in comments ;)

Have fun!

Leia este post em Português!

Mar 5, 2015

Co & Contra variance in C#

Hi
Every now and then I find myself thinking about 2 concepts that has “just” been “extended” in C# language version 4.0 ;): co / contravariance. The interesting fact is that it always seems like my brain is going to blow :)

PS: I used the words “just” and “extended” in quotes because version 4.0 of the language has been released in April/2010 (according to Wikipedia) and C# supported covariance (in some way or another) since version 1.0!

So, in order to try to assimilate the concept, once and for all, I decided to do what I believe to be the most effective way to learn, i.e, to try to explain it to others ;) so, if you already master the subject, go away, do something else :) (this will be an informal discussion about these topics. If you want a more formal one, please see this Wikipedia page and possible follow the links).

Basically, as the Wikipedia article (IMO) puts very well, variance refers to how type inheritance affects the relationship of more complex language constructs (such arrays of derived types instead of arrays of the base type, functions returning a derived type instead of a function return the base type, etc)

Take a look in the following piece of C# code:

using System;

namespace CoContraVariance
{
 class Base { }

 class Derived : Base { }

 class Program
 {
  static void Main(string[] args)
  {
   Derived[] derivedArray = new [] { new Derived(), new Derived() };
   Base[] baseArray = derivedArray;

   foreach (var item in baseArray)
   {
    Console.WriteLine(item);
   }
  }
 }
}


Pretty simple, huh?

In line 13 we create an array of Derived objects initialized with 2 objects; then on line 13 we assign this array to a variable declared as an ‘array of Base’ objects and it just works, after all, Derived inherits from Base, and developers expects such assignment to work.

But don’t get too excited about array covariance yet because… it is broken

The problem is that arrays in C# are covariant, pero no mucho. Suppose that in the next version of the program, you were tasked to, after printing the contents to console, replace the first element of the array with an instance of the Base class, so you come up with the following code:

namespace CoContraVariance 
{
  class Base { } 
  class Derived : Base { } 

  class Program 
  {
    static void Main(string[] args)
    { 
      Derived[] derivedArray = new [] { new Derived(), new Derived() }; 
      Base[] baseArray = derivedArray; 

      foreach (var item in baseArray) { System.Console.WriteLine(item); }

      baseArray[0] = new Base();
    }
  }
} 


Piece of cake, if you don’t mind an exception being thrown at line 13. Why? Well, because since arrays in C# are covariant, but pero no mucho, you can handle an array of a derived type as an array of a base class (like our sample) when you are reading from it, but not when you are assigning to it! It is even worse than that: every assignment need to be checked for type correctness so we are paying an extra performance price whenever we assign to any position of the array.

Another C# construct that supports co/contravariance since version 2.0 of the language is “method group to delegate conversions“. As an example, take a look in the following code:

void Foo(Func<Base> f)

{

}

Derived Bar()

{

}

Even though Foo is declared as taking a function that returns a reference to a Base object, it is perfectly valid to call it as:

Foo(Bar);

Why? Well, whatever value “f” (in this case Bar() method) returns to Foo it will be either an instance of Derived or of a sub class of Derived. In any case this object “is an” instance of Base, which Foo() is prepared to handle.

The converse is also valid for parameters (in this case it is called contravariance):

void Foo(Action<Derived> f)

{

}

void Bar(Base base)

{

}

Foo(Bar);

Note that, even though conversions from method group to delegates are co/contra variant since C# version 2.0, generic delegates are not! So, the following code is invalid on C# versions < 4.0

Action<Derived> ad = Bar; // Ok, valid, method group to delegate conversion (contravariance)

Action<Base> ac = Bar;

Action<Derived> ad_error = ac; // Error.

Ok, now, as every good C# dev is aware, arrays implements the IEnumerable<T> interface, so intuitively developers expect that the following change should be supported:


using System;
using System.Collections;
using System.Collections.Generic;

namespace CoContraVariance
{
 class Base { }

 class Derived : Base { }

 class Program
 {
  static void Main(string[] args)
  {
   Derived[] derivedArray = new [] { new Derived(), new Derived() };
   Base[] baseArray = derivedArray;

   foreach (var item in baseArray)
   {
    Console.WriteLine(item);
   }

   IEnumerable<Derived> deriveds = derivedArray;
   IEnumerable<Base> bases = deriveds;
  }
 }
}


But, if you try to compile this sample against C# version < 4.0 you’ll get an error in line 24 similar to:

Error CS0266: Cannot implicitly convert type ‘IEnumerable<Derived>’ to ‘IEnumerable<Base>’. An explicit conversion exists (are you missing a cast?)
This happens because in C# language, prior to version 4.0, generic interfaces were invariant, i.e, given an interface Itf<T> and types Base and Derived (Derived inheriting from Base) Itf<Derived> had no inheritance relationship with Itf<Base> whatsoever!

In C# version 4.0 the language designers introduced co/contra variance for generic interfaces and generic delegates! The first implication for us, is that, if we try to compile our previous sample (the one in which we play with IEnumerable<T>) with such C# compiler version it works! (that happens because MS annotated IEnumerable<T> as covariant).

The second implication for us is that now we can mark our very own interfaces as such!


namespace CoContraVariance 
{ 
  interface IFoo<out T>
  { 
    T GetValue();
  } 

  class Base { }
  class Derived : Base { } 

  class Program
  {
    static void Main(string[] args)     
    { 
      IFoo<Derived> derivedItf = null; 
      IFoo<Base> baseItf = derivedItf; 
    } 
  } 
} 


The first thing that pops out our eyes is the word “out” (no pun intended) besides the generic parameter “T” and that is the way we tell the compiler that the interface IFoo is covariant in T (if you remove this “marker” line 16 becomes invalid again).

Just in case it is not clear yet, covariant type parameters may only be used as the return type of methods / properties; if you try to define parameters of such types the compiler will kindly remind you that this is not valid ;)
The other language construct, called contravariance, allows us to handle generic interfaces / delegates of a base type as interface/delegate to a more derived one (IMO, contravariance is harder to grasp since it looks like it goes against the “normal” inheritance rules).


namespace CoContraVariance 
{ 
  interface IFoo<in T>
  { 
    void DoIt(T value);
  } 

  class Base { } 
  class Derived : Base { }   
  class MoreDerived : Derived { } 

  class Program 
  { 
    static void Main(string[] args) 
    { 
      IFoo<Base> baseItf = null; 
      IFoo<Derived> derivedItf = baseItf;

      derivedItf.DoIt( new Derived() );
      derivedItf.DoIt( new MoreDerived() );
    }
  } 
}


In this sample, when a call to derivedItf.DoIt() is made we’ll be calling baseItf.DoIt(). Since the compiler will enforce that anything we pass to the former inherits either directly or indirectly from Derived and that Derived “is a” Base, the actual method called will get an instance of Base (which is exactly what it expects)!

If you want to read more about it I recommend this excelent, in deph, series of posts and also the following links:

http://msdn.microsoft.com/en-us/library/ee207183.aspx

http://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

Happy codding.

May 24, 2014

Utilitário útil da semana: doskey

Read this post in English

Se você usa o console (cmd.exe) do Windows em suas tarefas diárias, você deve ser uma pessoa bem infeliz :)

Brincadeira a parte, deixe me explicar: você deveria usar um console melhor, e como eu frise, no windows temos algumas opções).

Mas o objetivo deste post é na realidade, falar sobre um utilitário que acompanha o Windows e que pode tornar sua experiência com consoles melhor; trata-se do doskey um aplicativo capaz, dentre outras coisas, de criar aliases, ou seja, "apelidos" para comandos (eu verifiquei no Windows 7 / 8 mas me lembro de utilizar um aplicativo com o mesmo nome no DOS 4.2).

No meu caso constantemente necessito abrir um arquivo texto em um editor (eu gosto muito to Sublime e também do Notepad++); para simplificar tal tarefa eu normalmente abro o console e a primeira coisa que eu digito é:
doskey subl = "%ProgramFiles%\Sublime Text 2\sublime_text.exe" $* 
a partir deste momento posso digitar o seguinte comando no console para abrir um arquivo de textos no Sublime:
subl meu-arquyivo-texto.ext

Bom fim de semana!

Happy coding.

Useful utility: doskey

Leia este post em Português

If you use the Windows console in your everyday tasks you probably is a very sad person :)

Let me explain, you should move to a better console ;) And we have a couple of options (as I stated here).

But this is not the focus of this post. My point is, if you rely on a console on Windows (whenever cmd.exe, ConEmu, whatever) and you want to be able to create aliases to applications you can use a built in command (at least on Windows 7 / 8) called doskey (you can find it in %windir%\System32\doskey.exe) (it probably exists on all Windows versions all way down to Windows 3.0 and even to DOS 4.2 - I remember using it on such OSs :).

For instance, if you want to make it more convenient to open a text file in Sublime (or any other text editor) type the following command at your console (replacing the path to sublime executable with the path to your text editor:
doskey subl = "%ProgramFiles%\Sublime Text 2\sublime_text.exe" $* 
and from now on, on that console, you can simply type:
subl my-text-file.ext
and your file will open in Sublime!

Hope you find this info useful.

Happy coding.

May 16, 2014

Módulo de acesso a redes TCP/IP ENC28J60

Ola

Já faz algum tempo que não posto nada sobre Arduino / sistemas embarcados; bom, como você já deve saber... ok, não vou usar a velha desculpa de falta de tempo.

Estou aqui para dizer que não estou estagnado no meu aprendizado sobre o Arduino e também para falar sobre minha última vitória; a mais ou menos um ano e meio, eu comprei um módulo Ethernet (ENC28J60) igual ao que segue abaixo para fazer alguns experimentos.

Acontece que eu nunca consegui fazer o mesmo funcionar; acabei apelando e comprando um Ethernet Shield (baseado no W5100) o qual funcionou sem maiores problemas. Outro dia eu estava mexendo nas minhas tralhas de eletrônica e encontrei o dito cujo (aquele que eu não havia conseguido fazer funcionar) e decidi que iria tentar novamente.

Depois de ler vários blogs, artigos, etc na internet, acabei obtendo sucesso. Abaixo segue a configuração que eu utilizei:
Veja abaixo como ficaram as conexões:

ArduinoENC28J60
ICSP
HEADER
MISOSO
MOSISI
SCKSCK
RESETRST
PINOS
I/O
VCC (3.3V)VCC
GNDGND
10CS
INT(2)INT






Veja abaixo um ótimo diagrama do Arduino Leonardo.



Observe que no Arduino Mega / Uno e outros, o conector ICSP também esta conectado aos pinos normais de I/O (mas não no Leonardo).


Como eu comentei, tive que fazer uma mudança na biblioteca utilizada para acessar o módulo. Básicamente no arquivo EtherCard/enc28j60.cpp eu mudei:

void ENC28J60::initSPI () {
    pinMode(SS, OUTPUT);
    digitalWrite(SS, HIGH);

    // rest of the code....
}

para:

void ENC28J60::initSPI () {
     pinMode(10, OUTPUT);
     digitalWrite(10, HIGH);


    // rest of the code....

Isso porque o pino SS esta definido com um valor (17) diferente do pino que eu escolhi, 10.

E pronto! Depois disso foi só abrir um dos exemplos da biblioteca, modificá-lo um pouco e temos temos um web server rodando no Arduino.

O que você acha? Eu acho isso muito massa ;)

Não hesite em deixar comentários / perguntas / sugestões / críticas.

Happy Coding.

OBS: Antes de postar eu notei no esquema de pinagens que no Leornardo o pino SS (17) é o pino A3; então teóricamente é possível utilizar a biblioteca citada sem modificações (basta ligar o pino CS do módulo no pino A3 do Arduino; teóricamente pois eu não testei :)

(Read this post in English)

Arduino Ethernet module ENC28J60

Hi

It has been some time since my last post about Arduino / embedded development, you know..... well, I'll not give the usual excuse of lack of time ;)

This post is about my last victory! Some one and half years ago I bought, a cheap, Ethernet module (ENC28J60) (similar to the one in the picture below) so I could do some experiments.

It happens that I failed miserably to get it working and I ended up ordering a Ethernet Shield (W5100) (which worked with no problems) and gave up on this module. 

Some days ago while I was checking my electronics junk stuff I found it again and decided I was ready to give it another try.

After reading a lot of blog posts, articles, documentation, etc, I finally succeeded and get it to work with the following configuration:
  • Arduino Leonardo
  • This library to access TCP/IP thought the ENC28J60 module (with the suggested modifications from this post) (which are only required / necessary for Arduino Leonardo)
  • Connections as described on the same post cited above.
To make it easier I posted the connections below:

ArduinoENC28J60
ICSP
HEADER
MISOSO
MOSISI
SCKSCK
RESETRST
I/O
PINS
VCC (3.3V)VCC
GNDGND
10CS
INT(2)INT






Below you can see a nice Arduino Leonardo diagram.



Note that on another Arduinos (like Mega / Uno), ICSP connector is also connected to the "normal I/O pins" but not on Leonardo so you must use the ICSP connector in order to connect the Arduino to the module.


The last piece that is missing was to change the file EtherCard/enc28j60.cpp as follows:

void ENC28J60::initSPI () {
    pinMode(SS, OUTPUT);
    digitalWrite(SS, HIGH);

    // rest of the code....
}

to:

void ENC28J60::initSPI () {
     pinMode(10, OUTPUT);
     digitalWrite(10, HIGH);


    // rest of the code....

This change was required because the SS constant is defined with a different value (17) than the pin I chosed (10).

Finished! Now it was only a matter of taking one of the ENC28J60 library examples, change it a little bit and some 60 mins later I had an web server running on my Arduino Leonardo.

What do you think? Pretty cool, IMO! :)

Happy Coding.

(Leia este post em Portugues)

Apr 23, 2014

C# 6.0: Open Source!

Olá
No post anterior eu comentei sobre algumas das possíveis funcionalidades da próxima versão do C#.

No evento Build 2014 (que ocorreu algumas semanas atras) a MS confirmou algumas destas funcionalidades bem como apresentou algumas que eu não tinha conhecimento (e que realmente gostei). Abaixo segue uma discussão das mesmas, começando por aquela que mais me animou:

Projeto Roslyn

A MS não apensas confirmou que a próxima versão dos compiladores C#/VB.Net serão baseados neste projeto, como surpreendeu muita gente ao anunciar que o mesmo agora é um projeto open source! Isso mesmo, você ouviu correto. Você já pode baixar o código fonte e ver com seus próprios olhos (inclusive muitas das funcionalidades anunciadas para a próxima versão do C# já funcionam com o compilador implementado baseado neste projeto).

Com esta abertura, subtamente, um monte de informação se tornou disponível. Por exemplo, você pode ver aqui a lista completa de funcionalidades para a próxima vesão do C# / VB.NET.

Apesar de, na minha opnião, baixar o código fonte e estudar o mesmo seja o caminho para aprender sobre o Roslyn, caso você não tenha tido contato com o mesmo anteriormente eu recomendo baixar/instalar o End user preview (na minha opnião, um caminho muito mais simples).

Propriedades automaticas (somente leitura)

Implementado; a medida que eu uso mais estes novos recursos eu gosto cada vez mais dos mesmos! :) Veja o exemplo abaixo (especial atenção à linha 3):
class Test(string name)
{
 public string Name { get; } = name;

 public static void Main(string[] args)
 {
  System.Console.WriteLine(new Test(args[0]).Name);
 }
}

“Primary Constructors”

Melhor do que eu esperava. Não apenas o comportamento dos parâmetros definidos em primary constructors obedecem as regras de escopo atuais como também é possível obter o resultado que eu propus no post anterior, ou seja, o conceito de “campos automáticos”. Veja o exemplo abaixo:

class Example (private int value, string n)
{
 private string name = n;

 public static void Main(string[] args)
 {
  new Example(42, "foo").Print();
 }

 private void Print()
 {
  System.Console.WriteLine("{0} = {1}", name, value);
 }
}
Observe que o campo value (usado na linha 12) nunca foi declarado explicitamente (pelo menos não usando-se a sintaxe tradicional)

“using” para membros estáticos (ou static using)

Lembra-se que eu comentei que não fiquei muito empolgado com esta funcionalidade? Pois é, depois de usá-lo bastante (ao escrever os exemplos deste post) estou começando a mudar de idéia ;)

Declaração inline para parâmetros out

Mais um uau! Acontece que meu entendimento da funcionalidade estava incorreta! Na realidade o nome correto da mesma é “declaration expressions” (desculpa, não sei uma boa tradução sem entrar em detalhes sobre conceitos de compiladores, o que não é meu objetivo neste post - além de não conhecer o assunto o suficiente).

Na prática, nesta nova versão, podemos declarar variáveis, por exemplo, na expressão de testes de if s, for s, etc.

Veja o exemplo abaixo:

using System.IO;
using System.Console;

class Test
{
 public static void Main(string[] args)
 {
  if (args.Length == 0)
  {
   WriteLine("arquivo?");
   return;
  }
  
  using(var arq = File.OpenText(args[0]))
  {
   while ( (var line = arq.ReadLine()) != null )
   {
    WriteLine("> {0}", line);
   }
  }  
 }
}
Note que na linha 16 declaramos a variável line na expressão de teste do bloco while!

Como sempre, quando bem utilizado, este recurso tem o potencial de eliminar “ruido” do código.



Funcionalidades que eu não estava ciente (e não comentei no post anterior)

Separadores em literais e constantes binárias

Ok, essa é mais uma “me too” copiado do Java ;)
Confesso que torci o nariz quando vi a funcionalidade implementada no Java, mas após usá-la algumas vezes acabei me convencendo da conveniência da mesma (infelizmente não esta implementado nesta preview ainda).

Basicamente, agora podemos usar o separador _ em valores de constantes além de declaras constantes binárias. Veja o exemplo:

class Test
{
 public static void Main(string[] args)
 {
  var value = 0xDEAD_BEEF;
  var bin = 0b00000100;
 }
}

Exception Filters

Na versão corrente do C# (5.0), cenários que demandam tratamento específico de exceções baseados em dados da mesma acabam sendo um tanto quanto difíceis. Imagine o exemplo abaixo:
class Example
{
 public void M()
 {
  try 
  { 
  } 
  catch(MyException me) 
  { 
   if (me.SomeProp == some_value) 
   { 
   // trata a exceção aqui 
   } 
   else 
   { 
    throw; 
   } 
  }
 }
}
O if dentro do bloco catch (linha 10) tem como único objetivo filtrar exceções baseado no valor de uma propriedade. A partir da versão 6.0 do C# a seguinte sitaxe é válida:
class Example
{
 public static void Main()
 {
  try 
  { 
  } 
  catch(MyException me) if (CheckException(me))
  { 
   // trata a exceção aqui 
  }
 }

    private static bool CheckException(MyException ex)
    {
        return ex.SomeProp == 42;
    }

}

class MyException : System.Exception
{
 public int SomeProp;
}
Eu, particularmente gostaria de poder usar uma sintaxe mais parecida com a declaração de uma expressão lambda:
class Example
{
 public static void Main()
 {
  try 
  { 
  } 
  catch(MyException me => me.SomeProp == 42)
  { 
   // trata a exceção aqui 
  }
 }
}

class MyException : System.Exception
{
 public int SomeProp;
}

Membros indexados

Esta funcionalidade tem como objetivo simplificar o processo de inicialização de tipos que sobrecarregam o operador de indexação [] introduzindo uma sintaxe alternativa, mais natural em alguns cenários:
using System.Collections.Generic;
using System.Console;

class Example
{
 private IDictionary<string, int> data = new Dictionary<string, int>();

 public int this[string i] 
 { 
  get { return data[i]; }
  set { data[i] = value ; }
 }

 public static void Main(string[] args)
 {
  var dic2 = new Dictionary<int, string>() 
  { 
   {0, "nada" },
   {1, "uno" }
  };

  var dic = new Dictionary<int, string>() { [0] = "nada", [1] = "uno" };   
  var inst = new Example { $zero = 0, $one = 1, $two = 2 };

  WriteLine("Hello World from roslyn! {0} {1}", inst.$zero, inst["zero"]);
 }
}
Outro ponto positivo é que esta sintaxe é válida também na inicialização de objetos.

Note que, além da sintaxe simplificada quando o operador de indexação utiliza strings, também pode-se utilizar a sintaxe de indexadores (quando a chave não é string).

Recurso muito bem vindo em minha opinião.

Extension “Add” Methods em inicializadores de coleções


Caso você nunca tenha usado “collection initializers” em seus programas veja o exemplo abaixo:

using System.Collections;

class Coll : IEnumerable
{
 public void Add(string s)
 {
  System.Console.WriteLine(s);
 }

 public IEnumerator GetEnumerator() { return null; }
}

class Test
{
 public static void Main(string[] args)
 {
  var x = new Coll() 
  { 
   "foo",
   "bar",
   "baz" 
  };
 }
}
A existência do método Add() (linhas 5 ~ 8) (bem como implementar IEnumerable) é uma condição indispensável para que a syntaxe de “Collection Initializers” (linhas 17 ~ 22) possa ser utilizada. Até a versão 5.0 (inclusive) do C# este método tinha que, obrigatóriamente, ser um método na hierarquia da classe.

A partir da versão 6.0 do C# Extension Methods também são suportados:
using System.Collections;

static class Extensoes
{
 public static void Add(this Coll coll, string s)
 {
  System.Console.WriteLine(s);
 }
}

class Coll : IEnumerable
{
 public IEnumerator GetEnumerator() { return null; }
}

class Test
{
 public static void Main(string[] args)
 {
  var x = new Coll() 
  { 
   "foo",
   "bar",
   "baz" 
  };
 }
}

Outras funcionalidades planejadas

Dentre as funcionalides comentadas no post anterior que ainda não foram implementadas mas que estão planejadas podemos citar:

  • Property Expressions / “Method expressions”: Na documentação do projeto aparecem com o nome de Expression-bodied members.
  • Enumerables como parâmetros do tipo “params”
  • Inferência de tipos a partir de parêmtros de construtores

Você pode ver a lista completa das funcionalidades planejadas / já implementadas para as próximas versões do C#/VB.NET nestes links.

O que você acha? (eu, particularmente, estou entusiasmado com o futuro da plataforma .Net!)