O Visual C# 2008 separável alterações

Alterações significativas no Visual 2008 translation from VPE for Csharp serviço empacotar 1

A tabela a seguir lista todas as alterações recentes Visual C# 2008 serviço empacotar 1 que podem afetar um aplicativo que foi criado na versão original do Visual C# 2008 ou no Visual C# 2005.

Alterar número

Category (Categoria)

Problema

Descrição

1

Resolução de sobrecarga

inferência de tipos de tipos agora está incluída em matrizes de tipos de ponteiro na resolução de sobrecarga de método.

No Visual C# 2008 e anteriores, inferência de tipos de tipos faz com que matrizes de tipos de ponteiro a serem excluídos do processo de resolução de sobrecarga de método.O código a seguir, o compilador do Visual C# 2005 seleciona a versão não-genéricas de Test porque a versão genérica do Test é excluído da consideração causa de seu parâmetro de tipo int*[]. No Visual C# 2008, a versão genérica de Test está selecionada.

using System.Collections.Generic;
unsafe class Program
{
    static void Main()
    {
        IEnumerable<int*[]> y = null;
        Test(y); 
    }
// Selected by Visual C# 2008.
    static void Test<S>(IEnumerable<S> x) { } // Selected by Visual C# 2005.
    static void Test(object o) { } 
}

2

Indexadores

Agora, o compilador produz erro CS0466 indexadores e propriedades, além de métodos.

Em versões anteriores e a versão original do Visual C# 2008, é possível definir uma implementação explícita de um indexador em que a implementação tem um params parâmetro, mas a definição de interface não permite. Essa construção é contrário à especificação.No Visual C# 2008 SP1, essa construção produz CS0466 de erro do compilador, sistema autônomo mostra o código a seguir.

interface I
{
    int this[int[] p] { set; }
}
class Base : I
{
// Produces CS0466:
    int I.this[params int[] p]    {
        set
        {
        }
    }

}

3

Tipos anuláveis e ?? expressões

Compilador agora corretamente avalia expressões nos quais variáveis anuláveis são comparadas entre si.

Na versão original do Visual C# 2008, o código a seguir compila e gera "false" em time de execução.No Visual C# 2008 serviço empacotar 1, Compilador CS1718 de aviso (nível 3)é gerada e "verdadeiro" é de saída.

static class Program
{
    static void Main()
    {
        int? x = null;
        bool y = x == x;
        Console.WriteLine(y);
    }
}

4

try-finally em iteradores

Execução do aninhados finally blocos de iteradores ter break instruções é alterado.

Na versão original do Visual C# 2008, o código a seguir executa a externa finally duas vezes. No Visual C# 2008 SP1, a externafinally é executado uma vez.

using System;
using System.Collections;
using System.Collections.Generic;
public class Test
{
    public static void Main()
    {
        Console.WriteLine("in main");
        foreach (int i in GetInts())
        {
            Console.WriteLine("in foreach");
            break; 
        }
    }
    static IEnumerable<int> GetInts()
    {
        Console.WriteLine("in GetInts");
        while (true)
        {
            Console.WriteLine("in while");
            try
            {
                Console.WriteLine("in outer try");
                try
                {
                    Console.WriteLine("in inner try before yield");
                    yield return 1;
                    Console.WriteLine("in inner try after yield");
                    break;
                }
                finally
                {
                    Console.WriteLine("in inner finally");
                }
            }
            finally
            {
                Console.WriteLine("in outer finally");
            }
        }
    }
}

5

Árvores de expressão

conversão boxing incorreta de método de expressões em árvores de expressão não ocorre.

Na versão original do Visual C# 2008, o código a seguir produz 7, 0.A linha Console.WriteLine(e.Compile()(default(T))); saídas zero porque S Processador in a box é incorretamente sendo Intel. No Visual C# 2008 SP1, não há conversão boxing ocorre e o programa gera 7, 7.

using System;
using System.Linq;
using System.Linq.Expressions;
class Program
{
    static void Main()
    {
        Test<S>();
    }
    static void Test<T>() where T : I
    {       
        Expression<Func<T, int>> e = x => x.SetX() + x.X;
// No boxing in SP1:
        Console.WriteLine(e.Compile()(default(T))); 
    }
}
interface I
{
    int X { get; }
    int SetX();
}
struct S : I
{
    public int X { get; private set; }
    public int SetX()
    {
        X = 7;
        return 0;
    }
}

6

Inicializadores de objeto

Inicialização de tipos de valor em inicializadores de objeto foi corrigida.

A versão original do Visual C# 2008, a variável localb no exemplo a seguir não foi inicializado corretamente e seus membros X tem um valor igual a zero. No Visual C# 2008 SP1, S.X inicializada corretamente como 1 em ambos new expressões.

using System;
using System.Linq;
using System.Linq.Expressions;
    class Program
    {
        static void Main()
        {
            Test<S>();
        }
        static void Test<T>() where T : I, new()
        {
            var a = new T();
            a.X = 1;
            Console.WriteLine(a.X);
            var b = new T { X = 1 };
            Console.WriteLine(b.X);
        }
    }
    interface I
    {
        int X { get; set; }
    }
    struct S : I
    {
        public int X { get; set; }
    }
// Original release version of Visual C# 2008 output: 1 0
// Visual C# 2008 SP1 output: 1 1

7

Conversões de tipo

nulo literais não são mais conversível em valores de enum.

No versão original do Visual C# 2008, nulo literais são em alguns casos, podem ser convertidas em valores de enum.No Visual C# 2008 SP1, CS1502 de erro do compilador e CS1503 de erro do compilador são produzidos se você tentar fazer isso, conforme mostrado no exemplo a seguir.

enum MyEnum
{
    Zero = 0,
    One = 1
}
class MyClass { }
class Program
{
    static void Main(string[] args)
    {
// Produces CS1502 and CS1503:
        Test((MyClass)null);         }
    static void Test(MyEnum x)
    {
        System.Console.WriteLine(x);
    }
}

8

Árvores de expressão

Árvore de expressão inválido agora lança a exceção correta.

Na versão original do Visual C# 2008, uma árvore de expressão que contenha uma telefonar de método para um método que não está no tipo especificado lança um System.Security.VerificationException. No Visual C# 2008 SP1, um System.ArgumentException é lançada, sistema autônomo mostra o código a seguir.

using System;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
class Program
{
    public struct S { }
    static void Main()
    {
        Type t = typeof(System.Enum);
        MethodInfo m = t.GetMethod("GetTypeCode");
        ParameterExpression p = Expression.Parameter(typeof(S), "s");
        Expression<Func<S, TypeCode>> e = Expression.Lambda<Func<S, TypeCode>>(
// Throws System.ArgumentException in Visual C# 2008 SP1:
            Expression.Call(p, m), p); 
        Func<S, TypeCode> f = e.Compile();
// Throws System.Security.VerificationException in the
// original release version of Visual C# 2008: 
        Console.WriteLine(f(new S())); 
    }
}

9

Atributos

CharSet.Unicode agora é propagada para tipos de auxiliar translation from VPE for Csharp gera para campos de matriz fixo.

O compilador translation from VPE for Csharp gera tipos auxiliar para encapsular arrays fixos.A versão original do Visual C# 2008 e versões anteriores, o layout da matriz é sempre ANSI, mesmo se o StructLayout atributo especifica CharSet.Unicode. Não havia nenhuma forma para alterar o que nos translation from VPE for Csharp código-fonte.No Visual C# 2008 SP1, qualquer valor CharSet for especificado no StructLayout atributo é usado para construir a classe auxiliar, sistema autônomo mostra o código a seguir.

using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
unsafe struct Test
{
    public fixed char Chars[8];
}
class Program
{
    static void Main(string[] args)
    {
    }
}
Original release version of Visual C# 2008 MSIL:
.class sequential ansi sealed nested public beforefieldinit '<Chars>e__FixedBuffer0'
       extends [mscorlib]System.ValueType
{
  // ... 
} // end of class '<Chars>e__FixedBuffer0'
Visual C# 2008 SP1 MSIL:
.class sequential unicode sealed nested public beforefieldinit '<Chars>e__FixedBuffer0'
       extends [mscorlib]System.ValueType
{
  // . . . 
} // end of class '<Chars>e__FixedBuffer0'

10

Verificação de estouro

stackalloc agora executa uma verificação de estouro.

Na versão original do Visual C# 2008, é possível que um stackalloc alocação falhar sem causar uma exceção. Isso é por causa de uma instrução mul não verificado na gerado Microsoft intermediate linguagem (MSIL) quando o comprimento da matriz é multiplicado pelo dimensionar de cada elemento.No Visual C# 2008 SP1, uma instrução mul.ovf é gerada em vez de mul, para que estouros de produzem um System.OverflowEx ception Quando a alocação é tentada em time de execução.

class Program
{
    static void Main(string[] args)
    {
        int var = 0x40000000;
        unsafe
        {
            // 0x40000000 * sizeof(int) does not fit in an int.
            int* listS = stackalloc int[var]; 
// Visual C# 2008 SP1: System.OverflowException.
            listS[0] = 5; 
// Original release version of Visual C# 2008: 
// System.NullReferenceException.
        }
    }
}

11

Operadores de consulta padrão

Consultas sobre coleções não genéricas agora usam semântica translation from VPE for Csharp projeção padrão.

Em expressões de consulta LINQ sobre coleções não genéricas, sistema autônomo System.Collections.ArrayList, o from cláusula da consulta é regravada pelo compilador para incluir uma telefonar para o Cast<T> operador. Cast<T> Converte todos os tipos de elemento para o tipo especificado na from cláusula da consulta. Além disso, na versão original do Visual C# 2008, a Cast<T> operador também executa algumas conversões de tipo de valor e conversões definidas pelo usuário. No entanto, essas conversões são executados usando o System.Convert classe em vez da semântica translation from VPE for Csharp padrão. Essas conversões também causar problemas significativos de desempenho em determinados cenários.No Visual C# 2008 SP1, a Cast<T> operador é modificado para lançar um InvalidCastException para o tipo de valor numérico e conversões definidas pelo usuário. Essa alterar elimina tanto a semântica de elenco translation from VPE for Csharp não padrão e o problema de desempenho.Essa alterar é ilustrada no exemplo a seguir.

using System;
using System.Linq;
class Program
{
    public struct S { }
    static void Main()
    {
        var floats = new float[] { 2.7f, 3.1f, 4.5f };
        var ints = from int i in floats 
                   select i;
// Visual C# 2008 SP1 throws InvalidCastException. 
        foreach (var v in ints) 
            Console.Write("{0} ", v.ToString());
        // The original release version of Visual C# 2008
        // compiles and outputs 3 3 4
    }
}

Alterações significativas na versão release original do Visual C# 2008

A tabela a seguir lista todas as alterações recentes na versão original do Visual C# 2008 que podem impedir que um aplicativo criado no Visual C# 2005 compilação ou que podem mudar seu comportamento em time de execução.

Alterar número

Category (Categoria)

Problema

Descrição

12

Conversões de tipo

Conversão de qualquer expressão de constante com valor de zero a enum agora é permitido.

Um literal 0 é implicitamente conversível para qualquer tipo enum.No Visual C# 2005 e versões anteriores do compilador, também há algumas expressões constante avaliados como 0, que pode converter implicitamente a qualquer tipo enum mas a regra que determina quais essas expressões são conversíveis não está claro.No Visual C# 2008, todas as expressões constante que são iguais a 0 podem ser convertidas implicitamente a qualquer tipo enum.

Isso poderia causar algumas alterações no comportamento do código existente, sistema autônomo resolução de sobrecarga de método baseia-se na ausência dessa conversão implícita.O código a seguir compila com êxito no Visual C# 2005 e compiladores anteriores, resolver a invocação do método do valor curto apenas para a sobrecarga de int.No Visual C# 2008, essa chamada é ambígua porque o valor curto também é implicitamente conversível no E. No Visual C# 2008, o comportamento é alterado para permitir a conversão de qualquer expressão de constante que é avaliada como zero.

public enum E
{
    Zero = 0,
    One = 1,
} 
class A
{
    public A(string s, object o)
    { System.Console.WriteLine("{0} => A(object)", s); } 
    public A(string s, E e)
    { System.Console.WriteLine("{0} => A(Enum E)", s); }
} 
class B
{
    static void Main()
    {
        A a1 = new A("0", 0);
        A a2 = new A("1", 1);
        A a3 = new A("(int) E.Zero", (int) E.Zero);
        A a4 = new A("(int) E.One", (int) E.One);
    }
}
Visual C# 2005 output:
0 => A(Enum E)
1 => A(object)
(int) E.Zero => A(object)
(int) E.One => A(object)
Visual C# 2008 output:
0 => A(Enum E)
1 => A(object)
(int) E.Zero => A(Enum E)
(int) E.One => A(object)

13

Atributos

Agora o erro ocorre quando o mesmo atributo TypeForwardedTo está presente duas vezes em um assembly.

No Visual C# 2005, nenhum erro é gerado se um assembly contém dois atributos sistema.tempo de execução.CompilerServices.TypeForwardedTo destino o mesmo tipo.No Visual C# 2008, CS0739 de erro do compilador é produzido, conforme mostrado no exemplo a seguir.

// Class1.cs
// Causes CS0739:
    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Test))]
    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Test))] 
    public class Test
    {
        public static int Main()
        {
            Test f = new Test();
            return f.getValue();
        }
    }
    // Library1.cs
    public class Test
    {
        public int getValue()
        {
            return 0;
        }

}

14

Erros de tipo

Foi adicionado um novo aviso sobre o uso de um membro de tipo de referência em uma struct.

Regras de atribuição definitiva para structs exigem que seja a estrutura de struct conjunto a uma instância existente do seu tipo ou que cada um dos seus membros ser atribuído antes que ela é referenciada.No Visual C# 2005, não é produzido nenhum aviso ou erro quando um membro de tipo de referência não atribuída de uma estrutura é usado.No Visual C# 2008, Compilador CS1060 de aviso (nível 1) é produzido, conforme mostrado no exemplo a seguir.

    public class U { public int i;}
    public struct T { public U u;}
    class Program
    {
        static void Main()
        {
            T t;
// Produces CS1060:    
            t.u.i = 0; 
        }
    }

15

Verificação de estouro

Verificação de intervalo em const Decimal de tipos foi corrigido.

No Visual C# 2005, quando você converter Const tipos decimal, verificação de intervalo não é sempre correto e erros do compilador incorreta podem resultar.No Visual C# 2008, o código a seguir produz o corrigir o erro: CS0031 de erro do compilador.

        static void Main()
        {
            const decimal d = -10m;
            unchecked
            {
                const byte b = (byte)d; //CS0031
            }
        }

16

Verificação de estouro

Out-of-Bounds conversões para long Agora, produza o erro de compilador correto.

No Visual C# 2005, o código a seguir não produz um erro do compilador.No Visual C# 2008, ela produz CS0031 de erro do compilador.

class Conversion 
    {
        static void Main() 
        {
            long l2 = (long) 9223372036854775808M; //CS0031 
        }
    }

17

Buffers de dimensionar fixo

Acessar um buffer de tamanho fixo em uma struct não seguro antes de atribuir um valor para o buffer agora produz um erro do compilador.

Regras de atribuição definitiva para ponteiros não seguros exigem que o ponteiro ser definida antes de cancelar a referência do ponteiro.No Visual C# 2005, quando um struct não seguro contém um ponteiro para uma matriz, acessar o ponteiro antes de atribuir um valor a ela não produziu um erro do compilador.No Visual C# 2008, isso produz CS0165 de erro do compilador, sistema autônomo mostra o código a seguir.

    unsafe class Test
    {
        static void Main()
        {
            S* ps;
            ps->i[0]++;        } // CS0165
    }
    unsafe struct S
    {
        public fixed int i[10];
    }

18

Efeitos colaterais agora são preservados em expressões unindo nulo.

Atribuição definitiva e o ?? operador.

No Visual C# 2005, em determinados cenários, os efeitos colaterais no lado esquerdo de um valor nulo concentração expressão não serão preservados.Em tais casos, o segundo Console.WriteLine demonstrativo no exemplo a seguir produzirá um erro de compilador incorreta afirmando que b é não atribuído. No Visual C# 2008, o mesmo código é compilado corretamente sem erro.

        static void Main()
        {
            int? a, b;
            a = null;
            Console.WriteLine((b = null) ?? 17);
// No error in Visual C# 2008:Console.WriteLine(a + b);  

}

19

try-finally em iteradores

The finally bloco agora é executado quando um iterador na try bloco elimina com continue ou goto.

No Visual C# 2005, em um try-finally construção, quando bloquear controle passa de um iterador na try bloco usando um goto ou continue demonstrativo, o finally bloco não é executado. No Visual C# 2008, a finally bloco é executado nesses casos.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DisposeTest
{
    class A : IDisposable
    {
        int m_n;
        internal A(int n)
        {
            m_n = n;
        }
        internal void Nothing() { }
        ~A()
        {
            Console.WriteLine("failed to dispose {0}", m_n);
        }
        #region IDisposable Members
        public void Dispose()
        {
            GC.SuppressFinalize(this);
            Console.WriteLine("dispose {0}", m_n);
        }
        #endregion
    }
    class Program
    {
        static IEnumerable<A> B()
        {
            for (int nCount = 0; nCount < 2; nCount++)
            {
                Console.WriteLine("loop start");
                using (A A = new A(nCount))
                {
                    Console.WriteLine("using start");
                    // Section 1.
                    // Dispose not called correctly in Visual C# 2005.
                    if ((nCount % 2) == 0)
                        continue;
                    // Section 2.
                    // Dispose not called correctly in Visual C# 2005.
                    yield return A;
                    Console.WriteLine("using end");
                }
                Console.WriteLine("loop end");
            }
            yield break;
        }
        static void Main(string[] args)
        {
            foreach (A A in B())
            {
                A.Nothing();
            }
            Console.ReadLine();
        }
    }

}

20

Interfaces e classes base

Construção de classe agora ignora implementações explícitas os mesmos membros da interface em classes base.

No Visual C# 2005, quando uma classe não oferece uma implementação de um membro da interface, o compilador substitui implementações de classe base, mesmo que elas são declaradas sistema autônomo implementações de interface explícita.Esse comportamento não está em conformidade com a especificação ECMA (European Computer Manufacturers associação).O Visual C# 2008 corretamente implementa a especificação.No exemplo a seguir, o Visual C# 2005 imprime "B.teste".Visual C# 2008 "A.teste" imprime corretamente e ignora oTest método na classe B porque é uma implementação explícita da interface.

using System;
interface ITest
{
    string Test { get; }
    string Test2 { get; }
}
class A : ITest
{
    public string Test { get { return "A.Test"; } }
    public string Test2 { get { return "A.Test2"; } }
}
class B : A, ITest
{
    string ITest.Test { get { return "B.Test"; } }
    string ITest.Test2 { get { return "B.Test2"; } }
}
class C : B, ITest
{
    string ITest.Test2 { get { return "C.Test2"; } }
}
class Program
{
    static void Main()
    {
        C c = new C();
        Console.WriteLine(c.Test); 
// Visual C# 2008: "A.Test"
    }

}

21

Atributos

Uso de um membro obsoleto agora gera um aviso do compilador.

Você pode marcar métodos com o Obsolete atributo de causar erros ou avisos em time de compilar se os métodos são chamados. Quando você coloca este atributo em métodos virtual, o atributo deve ser colocado no método base.Se o Obsolete atributo é colocado em um método substituir, ele não causará avisos ou erros do compilador na invocação. No Visual C# 2005, o compilador permitia que você coloca o Obsolete o atributo em um método de substituir, mesmo que o atributo não tenha qualquer efeito quando ele foi colocado lá. No Visual C# 2008, de aviso do compilador Compilador CS0809 de aviso (nível 1)produzido, "membro obsoleto 'A.Filename' substitui o membro não obsoleto 'erro.Filename'." O exemplo a seguir faz com que esse aviso.

class A : Error
{
    [System.ObsoleteAttribute("Obsolete", true)]
    public override string Filename
    {
        set
        {
        }
    }
    public static void Main() { }
}
public class Error
{
    public virtual string Filename
    {
        set
        {
        }
        get
        {
            return "aa";
        }
    }
}
class B
{
    void TT()
    {
        new A().Filename = "Filename";
    }
}

22

Erros de compilação

Uso do /pdb sem opção do compilador /debug Agora, produzirá um erro.

No Visual C# 2005, nenhum aviso ou erro é exibido quando você especificar o /pdb opção, mas não o /debug opção. Translation from VPE for Csharp Visual apenas cria uma criação para versão sem gerar arquivo .pdb.A versão original do Visual C# 2008, se você especificar /pdb sem especificar /debug, o compilador exibirá CS2036 de erro do compilador.

23

Erros de tipo

Um erro agora é produzido quando um switch condição será anulada.

No Visual C# 2005, nenhum erro será gerado quando um void invocação de método é usada em um comutador demonstrativo.No Visual C# 2008, CS0151 de erro do compilador é produzido.

class C
{
    static void Main()
    {
// Produces CS0151:
        switch (M()) 
        {
            default:
                break;
        }
    }
    static void M()
    {
    }

}

24

Verificação de estouro

constante Decimal para integral conversões agora produzem um erro do compilador diferentes.

No Visual C# 2005, o código a seguir produziria CS0133 de erro do compilador: "A expressão que está sendo atribuída a 'b' deve ser constante."

const byte b = unchecked((byte)256M);

No Visual C# 2008, CS0031 de erro do compilador é gerado: "Valor constante 256 ' M ' não pode ser convertido em um byte." Observe que o erro é produzido, mesmo que o unchecked modificador é aplicado.

25

Expressões constante

Especificação de mais de perto é seguida sobre expressões constante.

No Visual C# 2008, vários problemas foram corrigidos no qual Visual C# 2005 incorretamente permitiria variáveis e operadores em expressões de constante.No Visual C# 2005, o código a seguir é compilado sem erros.No Visual C# 2008, CS0165 de erro do compilador , Compilador CS0184 de aviso (nível 1) , e Compilador CS1718 de aviso (nível 3) são produzidos:

class Program
{
    public static int Main()
    {
        int i1, i2, i3, i4, i5;
        // 'as' is not permitted in a constant expression.
        if (null as object == null)
            i1 = 1;
        // 'is' is not permitted in a constant expression.
        if (!(null is object))
            i2 = 1;
        // A variable is not permitted in a constant expression.
        int j3 = 0;
        if ((0 == j3 * 0) && (0 == 0 * j3))
            i3 = 1;
        int j4 = 0;
        if ((0 == (j4 & 0)) && (0 == (0 & j4)))
            i4 = 1;
        int? j5 = 1;
// Warning CS1718: Comparison made to same variable:
        if (j5 == j5) 
 
            i5 = 1;
        System.Console.WriteLine("{0}{1}{2}{3}{4}{5}", i1, i2, i3, i4, i5);
        return 1;
    }
}

26

Erros de tipo

Agora, um erro é produzido quando um tipo estático é usado sistema autônomo um parâmetro em um delegado ou em uma expressão lambda.

No Visual C# 2005, nenhum erro é gerado se um tipo estático for usado sistema autônomo um parâmetro a um delegado ou método anônimo.Tipos estático não podem ser usados sistema autônomo sistema autônomo tipos de parâmetros do método porque não pode ser instanciadas.Versão do compilador Visual C# 2005 permite tipos estático sistema autônomo tipos de parâmetro em delegados e declarações de método anônimo.Se você passar nulo sistema autônomo parâmetro, tais delegados podem ser chamados.No Visual C# 2008, erro CS0721 de erro do compilador é gerada se um tipo estático for usado sistema autônomo um parâmetro a um delegado ou método anônimo, conforme mostrado no exemplo a seguir.

public static class Test { }
public class Gen<T> { }
// Produces CS0721:
delegate int D(Test f); 
public class TestB
{
    public static void Main()
    {
        D d = delegate(Test f) { return 1; };
    }

}

27

Tipos anuláveis e ?? expressões

Nenhum aviso é produzido quando você converter uma constante para um tipo que permite valor nulo antes de atribuí-lo a anulável (de um tipo maior).

No Visual C# 2005, o código a seguir produziria Compilador CS0219 de aviso (nível 3). No Visual C# 2008, nenhum aviso é gerado.

ushort? usq2 = (byte?)0;

28

Resolução de sobrecarga

Um erro agora é produzido quando a resolução de sobrecarga ambíguo ocorre em métodos anônimo.

Chamadas de método em métodos sobrecarregados devem ser resolvidas pelo compilador para determinar qual sobrecarga específica para invocar.Quando tipo de parâmetro de uma invocação é inferido parcialmente, a sobrecarga específica para invocar pode tornar-se ambíguo.Isso faz com que um erro do compilador.

No caso de um método anônimo que está sendo passado sistema autônomo um parâmetro delegado, tipo de delegado do método anônimo é inferido parcialmente.Isso pode levar à ambigüidade quando o compilador está selecionando a sobrecarga correta.

No Visual C# 2005, o compilador não sempre produz um erro quando não houver nenhuma sobrecarga melhor única para um método anônimo.No Visual C# 2008, CS0121 de erro do compilador é produzido, conforme mostrado no exemplo a seguir.

class Program
{
    static int ol_invoked = 0;
    delegate int D1(int x);
    delegate T D1<T>(T x);
    delegate T D1<T, U>(U u);
    static void F(D1 d1) { ol_invoked = 1; }
    static void F<T>(D1<T> d1t) { ol_invoked = 2; }
    static void F<T, U>(D1<T, U> d1t) { ol_invoked = 3; }
    static int Test001()
    {
// Produces CS0121:
        F(delegate(int x) { return 1; });         if (ol_invoked == 1)
            return 0;
        else
            return 1;
    }
    static int Main()
    {
        return Test001();
    }
}

29

Erros de tipo

Um erro é produzido agora se você declarar uma matriz de ponteiros para os tipos gerenciado.

Ponteiros não seguros para tipos de referência não são permitidos e que causem erros do compilador.No Visual C# 2005, é possível declarar uma matriz de ponteiros para os tipos gerenciado.No Visual C# 2008, CS0208 de erro do compilador é gerado: "Não é possível obter o endereço de obter o dimensionar da ou declara um ponteiro para um tipo gerenciado (' t ')."

unsafe class TestClass<T>
{
// Produces CS0208:
    static T*[] x = { }; 
// Produces CS0208:
    static void Test(T*[] arr) 
    {
    }
// Produces CS0208:
    static T*[] TestB() 
    {
        return x;
    }

}

30

Resolução de sobrecarga

Um aviso agora é produzido quando métodos de candidato de resolução de sobrecarga variam por apenas ref ou out.

No Visual C# 2005, quando o compilador translation from VPE for Csharp executa resolução de sobrecarga em tipos genéricos, ele não verifica se os argumentos de tipo fará com que o candidato a métodos variar por apenas ref ou out. sistema autônomo resultado, a escolha de métodos é da esquerda para o common linguagem tempo de execução (CLR) em time de execução e apenas ele seleciona o primeiro método na lista.No Visual C# 2008, Compilador CS1956 de aviso (nível 1) é produzido quando o compilador detecta que dois métodos de candidatos para a resolução de sobrecarga variará de acordo com a única ref ou out. Essa condição é ilustrada no exemplo a seguir.

using System;
class Base<T, S>
{
// Produces CS1956:
    public virtual void Test(out T x) 
    {
        Console.WriteLine("Test(out T x)");
        x = default(T);
    }
    public virtual void Test(ref S x)
    {
        Console.WriteLine("Test(ref T x)");
    }
}
interface IFace
{
    void Test(out int x);
}
class Derived : Base<int, int>, IFace
{
    static void Main()
    {
        IFace x = new Derived();
        int y;
        x.Test(out y);
    }

}

31

Tipos anuláveis e??expressões

Uma expressão com nulo no lado esquerdo concentração nulo não é avaliada sistema autônomo uma constante nula.

No Visual C# 2005, uma expressão com nulo no lado esquerdo concentração nulo é avaliada sistema autônomo uma constante nula.No Visual C# 2008, isso não é o caso.No alguns casos, o Visual C# 2005 comportamento permite que variáveis sejam tratadas incorretamente sistema autônomo definitivamente atribuído.O código a seguir compila e executa sem erros no Visual C# 2005, mas no Visual C# 2008, CS0165 de erro do compilador é gerado: "Uso de variável local não atribuído 'x'."

static void Main()
    {
        int x;
        if (null == (decimal?)(null ?? null)) x = 1;
        // Producers CS0165 in Visual C# 2008:
        System.Console.WriteLine(x);    
    }

Consulte também

Outros recursos

Guia de Introdução ao Visual C#

Date

History

Motivo

Julho de 2008

Tópico adicional.

Alteração de recurso do SP1.