.NET  - Usando diferentes linguagens em um mesmo projeto - CLSCompliant


 Você já tentou usar mais de uma linguagem em um mesmo projeto ? Já criou uma classe usando a linguagem VB .NET e a usou em um código C# ? Isso é possível ?

A plataforma .NET nos permite usar múltiplas linguagens em um mesmo projeto. Ela permite inclusive herdar uma classe VB .NET em uma classe C#.

Se você nunca tentou fazer isso pois achava que não era possível este artigo vai mostrar como fazer isso na prática.

Então vamos lá...

Recursos usados:

Criando os projetos no Visual Studio 2013 Community

Vamos usar VS 2013 Community Edition e criar uma solução com dois projetos :

  1. Um projeto do tipo Class Library usando a linguagem C#
  2. Um projeto do tipo Console Application usando a linguagem VB .NET

Então abra o VS 2013 Community clique em New Project;

Selecione a Other Projects Types  -> Visual Studio Solutions e selecione Blank Solution informando o nome Usando_Diferentes_Linguagens e clique em OK;

A  seguir no menu File clique em Add -> Project ;

Selecione a linguagem C# e o template Class Library e informe o nome ProjetoCSharp e clique em OK;

A seguir no menu PROJECT clique Add Class e informe o nome Pessoa. A seguir digite o código abaixo na classe Pessoa:

using System;
using System;
namespace Pessoa
{
    public class Pessoa
    {
        public void Imprimir()
        {
            Console.WriteLine("Método Imprimir() da classe Pessoa (C#)")
        }
    }
}

Agora vamos incluir um novo projeto na solução.

No menu FILE clique em Add -> Project e selecione a linguagem VB .NET e o template Console Application informando o nome ConsoleVBNET:

Antes de continuar inclua uma referência no projeto ConsoleVBNET ao projeto ProjetoCSharp.

Clique com o botão direito do mouse sobre o projeto ConsoleVBNET e selecione Add Reference. A seguir marque o projeto ProjetoCSharp:

Ainda no projeto ConsoleVBNET selecione o menu PROJECT e clique em Add Class e informe o nome Estudante. A seguir digite o código abaixo na classe Estudante:

Public Class Estudante
    Inherits ProjetoCSharp.Pessoa
    Public Sub Exibir()
        Console.WriteLine("Classe Estudante - linguagem VB .NET")
    End Sub
End Class

Agora no módulo do projeto ConsoleVBNET digite o seguinte código:

Imports ProjetoCSharp
Module Module1
    Sub Main()
        Dim estud As New Estudante()
        estud.Exibir()
        estud.Imprimir()
        Console.ReadLine()
    End Sub
End Module

Observe que no código acima criamos uma instância da classe Estudante (criada na linguagem VB .NET) e que herda da classe Pessoa (criada na linguagem C#) e temos acesso ao método de ambas as classes pelo mecanismos da herança.

Executando o projeto ConsoleVBNET teremos o seguinte resultado:

Funciona perfeitamente !!!.

Vamos agora incluir um novo método na classe Pessoa.cs do projeto CSharp:

using System;
namespace ProjetoCSharp
{
    public class Pessoa
    {
         public void Imprimir()
        {
            Console.WriteLine("Método Imprimir() da classe Pessoa (C#)");
        }
         public void imprimir()
         {
             Console.WriteLine("Método imprimir() da classe Pessoa (C#)");
         }
    }
}

Incluímos o método imprimir() usando agora caixa baixa, e, como a linguagem CSharp é case sensitive não há problema algum com isso.

Mas ao tentar executar o projeto ConsoleVBNET novamente iremos obter a seguinte mensagem:



O erro indica que o método imprimir() é ambíguo pois a linguagem VB .NET não é case sensitive e os métodos Imprimir() e imprimir() são os mesmos métodos enquanto que para a linguagem C# são métodos distintos.

E Agora ???

Para resolver este problema a plataforma .NET nos fornece uma maneira de tornar uma library de uma linguagem neutra, ou seja, ela permite definir algumas regras básicas que podem ser aplicadas a qualquer library.

Então para tornar o seu código compatível com outra linguagem você deve usar o atributo CLSCompliant para definir o seu assembly.

Você deve escrever código compatível com a CLS - Common Languagem Specification.

A Common Language Specification (CLS) é um conjunto de regras básicas e espera-se que uma linguagem .NET deve satisfazê-los. O C# suporta muitos códigos não compatível com CLS, principalmente, para apoiar e manter o legado. Escrevendo programas C# por meio de código compatíveis com CLS temos grande portabilidade entre outros programas .NET escritos em outras linguagens .NET.

A compatibilidade com CLS (Common Language Specification) geralmente se refere à afirmação de que as regras e restrições CLS estão sendo seguidas, entretanto, o conceito tem um significado mais específico dependendo se você estiver descrevendo código compatível com CLS ou ferramentas de desenvolvimento compatíveis com CLS, tal como um compilador. Ferramentas compatíveis com CLS podem ajudar a escrever código compatível com CLS.

Se você deseja que seu código seja compatível com CLS, você deve expor funcionalidades de um jeito que seja compatível com CLS nos seguintes locais:

Você pode marcar assemblies, módulos, tipos, e membros como compatíveis com CLS ou incompatíveis com CLS usando o CLSCompliantAttribute.

Alguns compiladores de linguagens compatíveis com CLS, como os compiladores C# ou Visual Basic, permitem que você especifique que você pretende que seu código seja compatível com CLS. Estes compiladores podem verificar por compatibilidade com CLS e permite que você saiba quando seu código usa uma funcionalidade que não é aceita pelo CLS. 

Os compiladores C# e Visual Basic permitem que você marque um elemento de programa como compatível com CLS, o que fará com que o compilador gere um erro em tempo de compilação se o código for incompatível com CLS.

Abaixo vemos a sintaxe para a linguagem VB .NET e C# mostrando um exemplo de como usar o CLSCompiant :

<Assembly: CLSCompliant(True)>
<CLSCompliant(True)> Public Class Teste
   Public Sub Metodo1(valor As UInt32)
   End Sub
   Public Shared Sub Main()
      Dim i As Integer = 2
      Console.WriteLine(i)
   End Sub   
End Class

 

using System;
[assembly: CLSCompliant(true)]
[CLSCompliant(true)]
public class Teste {
   public void Metodo1(UInt32 valor){ }
   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

 

VB .NET C#

A execução deste código produziria a seguinte mensagem de alerta:

C#         => warning CS3001: Argument type 'uint' is not CLS-compliant
VB.NET  => warning BC40028: Type of parameter 'value' is not CLS-compliant

Para evitar a mensagem você pode indicar que Metodo1 não é compatível conforme o código abaixo:

<Assembly: CLSCompliant(True)>
<CLSCompliant(True)> 
Public Class Teste
   <CLSCompliant(Flase)>
   Public Sub Metodo1(valor As UInt32)
   End Sub
   Public Shared Sub Main()
      Dim i As Integer = 2
      Console.WriteLine(i)
   End Sub   
End Class

 

using System;
[assembly: CLSCompliant(true)]
[CLSCompliant(true)]
public class Teste 
{
   [CLSCompliant(false)]
   public void Metodo1(UInt32 valor){ }
   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

 

VB .NET C#

Todos os assemblies que devem ser compatíveis com CLS devem ser marcados como tal. Um assembly que não está marcado como compatível com CLS é considerado como sendo incompatível com CLS. Assume-se que se nenhum atributo CLS for aplicado a um tipo, esse tipo tem a mesma compatibilidade com CLS que o assembly em que o tipo é definido. Da mesma forma, se nenhum atributo CLS for aplicado a um membro, considera-se que o membro tem a mesma compatibilidade com CLS do tipo que o define.

Não é possível marcar um elemento de programa como compatível com CLS se seu elemento delimitador não estiver marcado como compatível com CLS.

Assemblies, módulos e tipos pode ser compatíveis com CLS mesmo que algumas partes do assembly, módulo, ou tipo não sejam compatíveis com CLS, desde que duas condições sejam atendidas:

    1- Se o elemento estiver marcado como compatível com CLS, as partes que não são compatíveis com CLS devem ser marcadas usando o CLSCompliantAttribute com seu argumento definido como false.

    2- Um membro comparável alternativo compatível com CLS deve ser fornecido para cada membro que não é compatível com CLS.

Se você criar uma biblioteca de classes compatível com CLS, sua biblioteca terá uma garantia de interoperabilidade com uma grande variedade de linguagens de programação; portanto, a biblioteca tem mais probabilidade de ter uma base de clientes maior do que uma versão que seja incompatível com CLS.

Porque também nós éramos noutro tempo insensatos, desobedientes, extraviados, servindo a várias concupiscências e deleites, vivendo em malícia e inveja, odiosos, odiando-nos uns aos outros.
Mas quando apareceu a benignidade e amor de Deus, nosso Salvador, para com os homens,
Não pelas obras de justiça que houvéssemos feito, mas segundo a sua misericórdia, nos salvou pela lavagem da regeneração e da renovação do Espírito Santo,
Que abundantemente ele derramou sobre nós por Jesus Cristo nosso Salvador;
Para que, sendo justificados pela sua graça, sejamos feitos herdeiros segundo a esperança da vida eterna.

Tito 3:3-7

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti