Evitando duplicação matriz
-
03-07-2019 - |
Pergunta
De acordo com [MSDN: diretrizes de uso matriz] ( http://msdn.microsoft.com/en-us/library/k2604h5s (VS.71) .aspx) :
Propriedades matriz de Valor
Você deve usar coleções para evitar ineficiências código. No exemplo de código a seguir, cada chamada para a propriedade myObj cria uma cópia da matriz. Como resultado, 2n + 1 cópias da matriz vai ser criado no ciclo seguinte.
[Visual Basic]
Dim i As Integer
For i = 0 To obj.myObj.Count - 1
DoSomething(obj.myObj(i))
Next i
[C#]
for (int i = 0; i < obj.myObj.Count; i++)
DoSomething(obj.myObj[i]);
Além da mudança de myObj [] para ICollection myObj, o que mais você recomendaria? Só percebi memória que meu aplicativo atual está vazando: (
Graças;
EDIT:? Será que forçando C # para passar referências w / ref (segurança de lado) melhorar o desempenho e / ou uso de memória
Solução
Não, não é vazando memória - é apenas fazer o trabalho de coletor de lixo mais difícil do que poderia. Na verdade, o artigo do MSDN é um pouco enganador: se a propriedade criado um novo coleção cada vez que foi chamado, seria tão ruim (memória sábio) como com um array. Talvez pior, devido ao costume-over dimensionamento da maioria das implementações de cobrança.
Se você conhece um método / propriedade funciona, você sempre pode minimizar o número de chamadas:
var arr = obj.myObj; // var since I don't know the type!
for (int i = 0; i < arr.Length; i++) {
DoSomething(arr[i]);
}
ou ainda mais fácil, uso foreach
:
foreach(var value in obj.myObj) {
DoSomething(value);
}
Ambos únicas abordagens chamar a propriedade uma vez. A segunda é mais clara IMO.
Outros pensamentos; nomeá-lo um método! ou seja obj.SomeMethod()
- este conjuntos expectativa de que ela não funciona, e evita a obj.Foo != obj.Foo
indesejável (o que seria o caso de matrizes)
Finalmente, Eric Lippert tem uma boa artigo sobre este assunto .
Outras dicas
Assim como uma dica para aqueles que não usam o ReadOnlyCollection mencionado em algumas das respostas:
[C#]
class XY
{
private X[] array;
public ReadOnlyCollection<X> myObj
{
get
{
return Array.AsReadOnly(array);
}
}
}
Espero que isso possa ajudar.
Sempre que têm propriedades que são caros (como recriar uma coleção de plantão) que quer documentar a propriedade, afirmando que cada chamada incorre em um custo, ou eu armazenar em cache o valor como um campo particular. getters de propriedade que são caros, devem ser escritos como métodos. Geralmente, eu tento expor coleções como IEnumerable em vez de matrizes, obrigando o consumidor a utilização foreach (ou um recenseador).
Não vai fazer cópias de matriz a menos que você fazê-lo fazê-lo. No entanto, simplesmente passando a referência a uma matriz de propriedade privada por um objeto tem alguns efeitos colaterais desagradáveis. Quem recebe a referência é basicamente livre para fazer o que quiser com a matriz, incluindo alterar o conteúdo de uma forma que não podem ser controlados pelo seu proprietário.
Uma forma de prevenir não autorizada intromissão com a matriz é retornar uma cópia do conteúdo. Outro (um pouco melhor) é retornar uma coleção somente leitura.
Ainda assim, antes de fazer qualquer uma dessas coisas que você deve se perguntar se você está prestes a dar demasiada informação. Em alguns casos (na verdade, muitas vezes) é ainda melhor para manter a matriz privada, mas deixar que fornecem métodos que operam sobre o objeto possuí-lo.
myobj não vai criar novo item a menos que explicitamente criar um. de modo a tornar o uso da memória melhor eu recomendo usar coleção particular (lista ou qualquer) e expor indexador que irá retornar o valor especificado da coleção privada