Apenas por uma questão de integridade, aqui está um despejo cerebral de informações relacionadas ...
Como outros observaram, string
é um apelido para System.String
. Eles são compilados com o mesmo código, portanto, no tempo de execução, não há diferença alguma. Este é apenas um dos aliases em C #. A lista completa é:
object: System.Object
string: System.String
bool: System.Boolean
byte: System.Byte
sbyte: System.SByte
short: System.Int16
ushort: System.UInt16
int: System.Int32
uint: System.UInt32
long: System.Int64
ulong: System.UInt64
float: System.Single
double: System.Double
decimal: System.Decimal
char: System.Char
Além de string
e object
, os alias são todos para tipos de valor. decimal
é um tipo de valor, mas não um tipo primitivo no CLR. O único tipo primitivo que não possui um alias é System.IntPtr
.
Na especificação, os aliases de tipo de valor são conhecidos como "tipos simples". Os literais podem ser usados para valores constantes de todos os tipos simples; nenhum outro tipo de valor tem formas literais disponíveis. (Compare isso com o VB, que permite DateTime
literais e também possui um alias.)
Há uma circunstância em que você precisa usar os aliases: ao especificar explicitamente o tipo subjacente de uma enumeração. Por exemplo:
public enum Foo : UInt32 {} // Invalid
public enum Bar : uint {} // Valid
Isso é apenas uma questão de como a especificação define enum declarações - a parte após os dois pontos tem que ser o tipo integrante de produção, que é um símbolo de sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
... em oposição a um tipo de produção como usado por declarações variáveis, por exemplo. Não indica nenhuma outra diferença.
Finalmente, quando se trata de usar: pessoalmente, uso os aliases em todos os lugares para a implementação, mas o tipo CLR para qualquer API. Realmente não importa muito o que você usa em termos de implementação - a consistência entre sua equipe é boa, mas ninguém mais vai se importar. Por outro lado, é realmente importante que, se você se referir a um tipo em uma API, faça isso de maneira neutra em termos de idioma. Um método chamado ReadInt32
é inequívoco, enquanto um método chamado ReadInt
requer interpretação. O chamador pode estar usando um idioma que define um int
alias para Int16
, por exemplo. Os designers .NET framework seguiram esse padrão, bons exemplos sendo nos BitConverter
, BinaryReader
e Convert
classes.
string
é uma construção lexical da gramática C #, enquantoSystem.String
é apenas um tipo. Independentemente de qualquer diferença explícita mencionada em qualquer especificação, ainda existe essa diferença implícita que pode ser acomodada com alguma ambiguidade. A própria linguagem deve suportarstring
de uma maneira que a implementação não seja (completamente) obrigada a considerar para uma classe específica na BCL.