Eu tenho uma matriz X de 10 elementos. Eu gostaria de criar uma nova matriz contendo todos os elementos de X que começam no índice 3 e terminam no índice 7. Claro, posso escrever facilmente um loop que fará isso por mim, mas gostaria de manter meu código o mais limpo possível . Existe um método em c # que pode fazer isso por mim?
Algo como (pseudo código):
Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)
Array.Copy
não se encaixa nas minhas necessidades . Eu preciso que os itens na nova matriz sejam clones. Array.copy
é apenas um memcpy
equivalente do estilo C , não é o que estou procurando.
Respostas:
Você pode adicioná-lo como um método de extensão:
Atualize a re-clonagem (o que não era óbvio na pergunta original). Se você realmente quer um clone profundo; algo como:
Isso requer que os objetos sejam serializáveis (
[Serializable]
ouISerializable
). Você poderia facilmente substituir qualquer outro serializer conforme o caso -XmlSerializer
,DataContractSerializer
, protobuf-net, etc.Observe que o clone profundo é complicado sem serialização; em particular,
ICloneable
é difícil confiar na maioria dos casos.fonte
Você pode usar
Array.Copy(...)
para copiar para a nova matriz depois de criá-la, mas não acho que exista um método que crie a nova matriz e copie uma série de elementos.Se você estiver usando o .NET 3.5, poderá usar o LINQ:
mas isso será um pouco menos eficiente.
Veja esta resposta a uma pergunta semelhante para opções para situações mais específicas.
fonte
Você já pensou em usar
ArraySegment
?http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx
fonte
IEnumerable<T>
e uma variedade de outras interfaces úteis.ArraySegment
para responder à pergunta original?IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
Vejo que você deseja fazer Clonagem, não apenas copiar referências. Nesse caso, você pode usar
.Select
para projetar membros da matriz em seus clones. Por exemplo, se seus elementos foram implementados,IClonable
você poderia fazer algo assim:Nota: Esta solução requer o .NET Framework 3.5.
fonte
IEnumerable
. Posso obter umIEnumerable
,IList
,IArray
, etc ... com o mínimo de barulho, inline se eu precisar. Se eu não precisar da cópia em profundidade, apenas removo aSelect
. Deixar cairSkip
ouTake
me permite controlar o alcance. Alternativamente, eu posso misturar comSkipWhile
e / ouTakeWhile
.O código a seguir faz isso em uma linha:
fonte
No C # 8, eles introduziram um novo
Range
eIndex
digitefonte
fonte
Com base na resposta de Marc, mas adicionando o comportamento de clonagem desejado
E se a implementação do ICloneable é muito parecida com o trabalho árduo, é necessário usar a biblioteca Copyable da Håvard Stranden para fazer o trabalho pesado necessário.
Observe que a implementação OX.Copyable funciona com qualquer um dos seguintes:
Portanto, isso deve cobrir quase todas as situações que você tiver. Se você estiver clonando objetos em que o subgrafo contém itens como conexões db ou identificadores de arquivo / fluxo, obviamente você tem problemas, mas isso é verdade para qualquer cópia profunda generalizada.
Se você quiser usar alguma outra abordagem de cópia profunda, este artigo lista várias outras, então eu sugiro que não tente escrever sua própria.
fonte
Você pode fazer isso facilmente;
fonte
Eu acho que o código que você está procurando é:
Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)
fonte
Como alternativa à cópia dos dados, você pode criar um wrapper que dê acesso a uma parte da matriz original como se fosse uma cópia da parte da matriz. A vantagem é que você não recebe outra cópia dos dados na memória, e a desvantagem é uma pequena sobrecarga ao acessar os dados.
Uso:
fonte
Array.ConstrainedCopy funcionará.
fonte
Não existe um método único que faça o que você deseja. Você precisará disponibilizar um método clone para a classe em sua matriz. Então, se LINQ é uma opção:
fonte
Que tal usar Array.ConstrainedCopy :
Abaixo está o meu post original. Isso não vai funcionar
Você poderia usar Array.CopyTo :
fonte
Que tal agora:
Você precisa implementar a interface ICloneable em todas as classes nas quais você precisa usá-lo, mas isso deve ser feito.
fonte
Não tenho certeza de quão profundo é realmente, mas:
MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()
É um pouco caro, mas pode resultar em um método desnecessário.
fonte
O C # 8 forneceu o recurso chamado Range para obter subárvores do início ao fim do índice. você pode usá-lo assim.
fonte
No que diz respeito à clonagem, não acho que a serialização chame seus construtores. Isso pode quebrar os invariantes de classe se você estiver fazendo coisas interessantes no ctor.
Parece que a aposta mais segura são os métodos de clone virtual que chamam construtores de cópias.
fonte
A clonagem de elementos em uma matriz não é algo que pode ser feito de maneira universal. Deseja clonagem profunda ou uma cópia simples de todos os membros?
Vamos seguir a abordagem do "melhor esforço": clonar objetos usando a interface ICloneable ou serialização binária:
Esta não é uma solução perfeita, porque simplesmente não existe uma que funcione para qualquer tipo de objeto.
fonte
Você pode assistir às aulas da Microsoft:
e depois
fonte
Descobri que esta é a maneira ideal:
Espero que ajude!
fonte
use o método de extensão:
e você pode usá-lo
fonte
Código do System.Private.CoreLib.dll:
fonte
Ele não atende aos seus requisitos de clonagem, mas parece mais simples do que muitas respostas:
fonte
fonte