Pergunta

Se eu estou construindo uma string usando um objeto StringBuilder em um método, faria sentido para:

retornar o objeto StringBuilder, e deixar o ToString chamada código de chamada ()?

return sb;

ou retornar a string chamando ToString () eu mesmo.

return sb.ToString();

Eu acho que faz diferença se estamos retornando pequeno, ou grandes cadeias. O que seria apropriado em cada caso? Agradecemos antecipadamente.

Edit: Eu não planeja modificar ainda mais a corda no código de chamada, mas bom ponto de Colin Burnett.

Principalmente, é mais eficiente para retornar o objeto StringBuilder, ou a corda? Seria uma referência para a cadeia se voltou, ou uma cópia?

Foi útil?

Solução

Voltar a StringBuilder se você estiver indo para modificar ainda mais a corda, caso contrário, retorna a string. Esta é uma questão API.

Com relação à eficiência. Uma vez que esta é uma pergunta vaga / general sem quaisquer especificidades então eu acho mutável vs. imutável é mais importante do que o desempenho. Mutabilidade é uma questão API de deixar o seu retorno API objetos modificáveis. comprimento da corda é irrelevante para isso.

Dito. Se você olhar para StringBuilder.ToString com refletor:

public override string ToString()
{
    string stringValue = this.m_StringValue;
    if (this.m_currentThread != Thread.InternalGetCurrentThread())
    {
        return string.InternalCopy(stringValue);
    }
    if ((2 * stringValue.Length) < stringValue.ArrayLength)
    {
        return string.InternalCopy(stringValue);
    }
    stringValue.ClearPostNullChar();
    this.m_currentThread = IntPtr.Zero;
    return stringValue;
}

Você pode ver que pode fazer uma cópia, mas se você modificá-lo com o StringBuilder, então ele irá fazer uma cópia, em seguida, (isto é o que eu posso dizer a ponto de m_currentThread é porque cheques acrescentar este e irá copiá-lo se ele não corresponde a thread atual).

Eu acho que o final deste é que se você não modifique o StringBuilder, então você não copiar a corda e comprimento é irrelevante para a eficiência (a menos que você bater esse segundo caso).

Atualizar

System.String é uma classe que significa que é um tipo de referência (em oposição ao tipo de valor), de modo "foo cadeia;" é essencialmente um ponteiro. (Quando você passar uma string em um método passa o ponteiro, não uma cópia.) System.String é mutável mscorlib dentro, mas fora imutável dela que é como StringBuilder pode manipular uma string.

Assim, quando ToString () é chamada, ela retorna seu objeto de cadeia interna por referência. Neste ponto, você não pode modificá-lo, porque seu código não está em mscorlib. Definindo o campo m_currentThread a zero, em seguida, quaisquer outras operações sobre o StringBuilder fará com que ele copiar o objeto string para que possa ser modificado e não modificar o objeto string que retornou em ToString (). Considere o seguinte:

StringBuilder sb = new StringBuilder();
sb.Append("Hello ");

string foo = sb.ToString();

sb.Append("World");

string bar = sb.ToString();

Se StringBuilder não fez uma cópia, em seguida, no foo final seria "Olá Mundo", porque o StringBuilder modificou. Mas desde que fez uma cópia, em seguida, foo ainda é apenas "Olá" e bar é "Olá Mundo".

O que esclarecer a coisa toda retorno / referência?

Outras dicas

Eu não acho que o desempenho deve ser um fator nessa questão. De qualquer forma, alguém vai chamar sb.ToString () para que o seu vai levar a algum lugar hit.

A questão mais importante é o que é a intenção do método eo propósito. Se este método faz parte de um construtor que você pode devolver o construtor de string. Caso contrário, eu iria retornar uma string.

Se isso é parte de uma API pública eu inclinar-se para devolver uma cadeia em vez do construtor.

Eu diria que o método deve retornar sb.ToString (). Se a lógica em torno da criação do objeto StringBuilder () deve mudar no futuro, faz sentido para mim que ser alterado no método não em cada cenário que chama o método e, em seguida, passa a fazer outra coisa

StringBuilder é um detalhe de implementação do seu método. Você deve retornar corda até que se torne um problema de desempenho, em que ponto você deve explorar um outro padrão (como visitante Padrão ) que pode ajudá-lo a introduzir engano e protegê-lo contra as decisões de implementação interna.

Cordas são sempre armazenados na pilha, assim você terá uma referência retornada se o tipo de retorno é string. Você não pode contar, no entanto, em duas cadeias idênticas de ter referências idênticas. Em geral, é seguro para pensar em uma string como se fosse um tipo de valor, mesmo que na verdade é um tipo de referência.

Eu acho que depende do que você está fazendo com a corda uma vez que deixa o método. Se você estiver indo para continuar anexando a ele, então você pode querer considerar retornando um stringbuilder para maior eficiência. Se você está sempre indo para chamar .ToString () sobre ele, então você deve fazer isso dentro do método para melhor encapsulamento.

eu gostaria de voltar a string em quase todas as situações, especialmente se o método é parte de uma API pública.

Uma exceção seria se o seu método é apenas uma parte de um processo maior, privado "construtor" e o código de chamada estará fazendo mais manipulações. Nesse caso, então eu talvez consideraria voltar a StringBuilder.

Uma vez que o seu não vai modificá-lo mais

return sb.ToString();

deve ser mais eficiente

Voltar a sb.ToString (). Seu método deve se concentrar em apenas uma coisa na mão (Neste caso, constrói-me uma string) e não ser devolvido para ser ainda mais manipulados IMO, você poderia entrar em todos os tipos de problemas com ele não ser descartado.

Depende do que você está pensando em fazer com a saída. Eu gostaria de voltar uma string pessoalmente. Dessa forma, se você precisa mudar o método abaixo da estrada para não usar um stringbuilder, você pode como você não vai ser preso com isso como um valor de retorno.

Ao pensar nisso no momento, a resposta é muito mais clara. A questão de perguntar o que deve ser devolvido realmente responde à pergunta. O objeto de retorno deve ser uma string. A razão é que se você está fazendo a pergunta: "Existe uma razão para retornar o objeto StringBuilder quando uma cadeia vai fazer?" em seguida, a resposta é não. Se houvesse uma razão, então corda retornando seria fora de questão, porque os métodos e propriedades do stringbuilder são necessários.

Se você precisar acrescentar mais coisas para a cadeia e utilizar outras funcionalidades relacionadas stringbuilder, devolver o stringbuilder. Caso contrário, se você está apenas usando a própria string, retorna a string.

Há outras considerações mais técnicas, mas isso é o mais alto preocupações nível.

O método foi dada uma tarefa concreta e deve ser esperado para completá-lo e devolver o resultado final que não requer mais processamento. Apenas retornar StringBuilder quando você realmente precisa dele. Nesse caso também adicionar algo para o nome do método para indicar que você está retornando algo especial.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top