2014-12-23 2 views
-1

Я, вероятно, что-то пропустил, но, как я понимаю, строка и строка являются псевдонимами, как описано в difference-between-string-and-string, поэтому строка - это всего лишь объект!Инициализация строк в .Net

Теперь я не понимаю, как следующий код инициализирует новый объект String?

string s="Hello World" 

Могу ли я сделать этот трюк для обычных объектов?

+0

aliase и объекты - это две разные вещи. – Codeek

+0

Я знаю, но как инициализируется объект String? –

+0

Как вы думаете, это будет работать для других типов? –

ответ

2

Если вы компилируете их в коде .. они являются константами времени компиляции .. то есть код явно ссылается на них из вашего скомпилированного двоичного файла, который, конечно же, загружается в память во время выполнения.

Если вы построите их во время выполнения .. как из массива char, я бы предположил, что для этого CLR необходима реализация. Например - посмотреть на следующий код из http://referencesource.microsoft.com/#mscorlib/system/string.cs,97ccd50b20126543

[System.Security.SecuritySafeCritical] // auto-generated 
private static String ConcatArray(String[] values, int totalLength) { 
    String result = FastAllocateString(totalLength); 
    int currPos=0; 

    for (int i=0; i<values.Length; i++) { 
     Contract.Assert((currPos <= totalLength - values[i].Length), 
      "[String.ConcatArray](currPos <= totalLength - values[i].Length)"); 

     FillStringChecked(result, currPos, values[i]); 
     currPos+=values[i].Length; 
    } 

    return result; 
} 

[System.Security.SecurityCritical] // auto-generated 
[ResourceExposure(ResourceScope.None)] 
[MethodImplAttribute(MethodImplOptions.InternalCall)] 
internal extern static String FastAllocateString(int length); 

По сути строки получить специальную обработку на языке, и хотя они являются объектами (неизменные), вы правы в своем понимании того, что они не реализованным с new оператором в традиционном смысл. т. е. вы не делаете то, что сказали в своем комментарии String s=new String("Hello World");, потому что если вы думаете об этом, то new является избыточным, потому что вы уже определили свою строку в двойных кавычках как строковый литерал.

И, следовательно, в то время как вы могли бы использовать оператор неявного, чтобы преобразовать строку в заданный тип .. Это неже трюк. Трюк в случае строк - это встроенная поддержка CLR.

EDIT: Вот еще одно доказательство. Существует специальный IL OpCode для загрузки строк. OpCodes.Ldstr

«Отбрасывает ссылку на новый объект на строковый литерал, хранящийся в метаданных».

Если вы посмотрите на свой скомпилированный код, вы увидите код операции ldstr, который будет использоваться для загрузки строк, а не newobj opcode.

+0

Nice +1 для ldstr! –

2

Как отметил @KirkWoll из Using Conversion Operators вы могли бы использовать оператор неявного

Что-то вроде

public class FOO 
{ 
    private string _foo; 

    public static implicit operator FOO(string foo) 
    { 
     FOO f = new FOO {_foo = foo}; 
     return f; 
    } 
} 

и затем вызвать его

FOO bar = "TADA"; 
Смежные вопросы