Что проку от Системы. Строка. Копия в.NET?

Итак, я сделал вторую попытку моего первого подхода, и мне удалось заставить его работать.

Я определил свои SegmentEnums

enum RouteSegment1 {
  value1,
  value2
}

enum RouteSegment2 {
  value1,
  value2
}

Создал охрану

export class EnumRouteGuard implements CanActivate {

  constructor(private router: Router) { }

  public canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const segment1: string = next.paramMap.get('routeSegment1')!;
    const segment2: string = next.paramMap.get('routeSegment2')!;

    const segment1IsEnum = Object.keys(RouteSegment1).find(key => RouteSegment1[key] === segment1);
    const segment2IsEnum = Object.keys(RouteSegment2).find(key => RouteSegment2[key] === segment2);

    if (!(segment1IsEnum && segment2IsEnum) ) {
      this.router.navigate([someOtherRoute]);
      return false;
    }
    return true;
  }
}

И использовал их в моих маршрутах

const routes: Routes = [
  {
    path: '', component: ParentComponent, children: [
      {
        path: ':routeSegment1',
        component: RouteSegment1Component,
         canActivate: [EnumRouteGuard],
      },
      {
        path: ':routeSegment1/:routeSegment2',
        component: RouteSegment2Component,
        canActivate: [EnumRouteGuard],
      },
    ],
  },
];
63
задан John Cummings 10 August 2018 в 01:10
поделиться

7 ответов

С String.Copy Вы на самом деле выделяете новую память и копируете символы от одной строки до другого; Вы получаете абсолютно новый экземпляр в противоположность наличию обеих переменных, являющихся тем же экземпляром. Это может иметь значение, используете ли Вы строку с неуправляемым кодом, который имеет дело с ячейками памяти непосредственно и может видоизменить строку.

40
ответ дан Hakan Fıstık 24 November 2019 в 16:24
поделиться

String.Copy возвраты новое String и не приводит к тем же результатам как [1 111]

String copy = otherString;

Попытка это:

using System;

class Program
{
    static void Main()
    {
        String test = "test";
        String test2 = test;
        String test3 = String.Copy(test);

        Console.WriteLine(Object.ReferenceEquals(test, test2));
        Console.WriteLine(Object.ReferenceEquals(test, test3));

        Console.ReadLine();
    }
}

, Когда Вы устанавливаете test2 = test, эти ссылки указывают на тот же String. Copy функция возвращает новое String ссылка, которая имеет тот же содержание , но как другой объект на "куче".

<час>

Редактирование: существует много людей, которые довольно расстроены, что я не отвечал на вопрос OP. Я полагаю, что действительно отвечал на вопрос путем исправления неправильной предпосылки в самом вопросе. Вот аналогичное (если не упрощено) вопрос, и ответьте, что это, надо надеяться, проиллюстрирует мой тезис:

Вопрос:

я заметил, что мой автомобиль имеет две двери, один на каждой стороне автомобиля. Я полагаю, что это верно, что, независимо от которой двери я использую, я закончу тем, что сидел у руля. Какова цель другой двери?

Ответ:

На самом деле это не верно, что при использовании любой двери, Вы закончите у руля. При использовании боковой двери драйвера, Вы закончите у руля и если Вы будете использовать боковую дверь пассажира, то Вы закончите в сиденье пассажира.

Теперь в этом примере Вы могли утверждать, что ответ не является действительно ответом, поскольку вопрос был, "какова цель боковой двери пассажира?". Но так как тот вопрос полностью был основан на неправильном представлении, как двери работали разве, он не следует за этим, опровержение предпосылки прольет новый свет на цель другой двери вычетом?

20
ответ дан Andrew Hare 24 November 2019 в 16:24
поделиться

Вот одна часть загадки. Это не объясняет, почему Вы хотели бы сделать это, но это действительно помогает объяснить функциональное различие.

при прикреплении строки с помощью fixed ключевое слово содержание было бы изменяемо. Первое, что пришло на ум я не могу думать о ситуации, в которой Вы хотели бы сделать это, но это возможно.

string original = "Hello World";
string refCopy = original;
string deepCopy = String.Copy(original);

fixed(char* pStr = original)
{
   *pStr = 'J';
}

Console.WriteLine(original);
Console.WriteLine(refCopy);
Console.WriteLine(deepCopy);
<час>

Вывод:

Jello World
Jello World
Hello World
20
ответ дан Kennet Belenky 24 November 2019 в 16:24
поделиться
string a = "abc";
string b = String.Copy(a);

Monitor.Enter(a); // not the same as Monitor.Enter(b);

Однако

string c = "123";
string d = c;
Monitor.Enter(c); // the same as Monitor.Enter(d);

относительно пути любой будет заботиться, я думаю, что это там для полноты.

<час>

Также

StringBuilder sb = new StringBuilder(100);
sb.Append("abc");
string a = sb.ToString();
string b = String.Copy(a);

я думаю a, поднимет больше RAM затем b, как a точки к буферу размера 100, который эти StringBuilder создал. (Посмотрите на внутреннюю часть StringBuilder.ToString() метод)

<час>

я думаю StringBuilder, использует String.Copy(), и быть частью платформы.NET StringBuilder действительно изменяет содержание string. Так string не всегда неизменно.

8
ответ дан Wai Ha Lee 24 November 2019 в 16:24
поделиться

В дополнение к какой сказанный tvanfosson (я не думаю, что можно получить доступ к буферу, используемому управляемой строкой из неуправляемого кода... Я знаю, что это было бы трудно, по крайней мере), я полагаю, что может быть различие, если строка используется в качестве объекта сделать блокировку на для многопоточной функциональности.

, Например...

using System;

public class Class1
{
    string example1 = "example";
    string example2 = example1;

    public void ExampleMethod1()
    {
        lock (example1)
        {
            Console.WriteLine("Locked example 1");
            //do stuff...
        }
    }

    public void ExampleMethod2()
    {
        lock (example2)
        {
            Console.WriteLine("Locked example 2");
            //do stuff
        }
    }
}

я верю, выполняются ли два метода в качестве примера параллельно, они будут блокировать тот же объект, и таким образом каждый не сможет выполниться, в то время как другой в его блоке блокировки.

Однако, если Вы изменяете его на это...

using System;

public class Class1
{
    string example1 = "example";
    string example2 = string.Copy(example1);

    public void ExampleMethod1()
    {
        lock (example1)
        {
            Console.WriteLine("Locked example 1");
            //do stuff...
        }
    }

    public void ExampleMethod2()
    {
        lock (example2)
        {
            Console.WriteLine("Locked example 2");
            //do stuff
        }
    }
}

Затем я полагаю, что они только заблокируют выполнение других потоков, выполняющих тот же метод (т.е. любые потоки, выполняющие ExampleMethod1, будут заблокированы, пока каждый не завершается, но они не вмешаются в потоки, выполняющие ExampleMethod2).

Не уверенный это полезно различие, так как существуют лучшие механизмы для синхронизации (я не думаю, блокируя строки, очень хорошая идея).

1
ответ дан 24 November 2019 в 16:24
поделиться
string a = "test";
string b = a;
//Object.ReferenceEquals(a,b) is true
a += "more";
//Object.ReferenceEquals(a,b) is now false !

обнаружение автоизменения?

0
ответ дан wiwulo 24 November 2019 в 16:24
поделиться

Я не уверен, как Строка, реализовываемая в.NET, но я думаю, что Java является хорошей ссылкой.

В Java, новая Строка (ул.) также делает что String.copy (ул.); сделайте, выделите новую Строку с тем же значением.

Это кажется бесполезным, но это очень полезно в оптимизации памяти.

Строка содержит символ [] со смещением и длиной в реализации. Если Вы сделаете что-то как подстрока, то это не сделает копии памяти, но возвратит новый Строковый экземпляр, совместно использующий тот же символ []. Во многих случаях этот шаблон сохранит много копии памяти и выделения. Однако, если Вы подстрока маленькая часть в длинной большой Строке. Это все еще сошлется к большому символу [], даже исходная большая Строка может быть GC.

String longString = // read 1MB text from a text file
String memoryLeak = largeString.substring(100,102); 
largeString=null;
// memoryLeak will be sized 1MB in the memory
String smaller = new String(largeString.substring(100,102));
// smaller will be only few bytes in the memory

Это может вызвать новый Строковый объект, выделяют свой собственный символ [] для предотвращения скрытой утечки памяти / отходы.

-1
ответ дан Dennis C 24 November 2019 в 16:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: