Por que HashSet, mas não Situado em C #?
Pergunta
velha questão
O meu entendimento é que C # tem em alguns tipos HashSet
sentido e set
. Eu entendo o que HashSet
é. Mas por set
é uma palavra separada? Por que nem todo conjunto é HashSet<Object>
?
New questão
Por que o C # não tem nenhum tipo Set
genérica, semelhante ao tipo Dictionary
? Do meu ponto de vista, eu gostaria de ter um conjunto com desempenho de pesquisa / adição / exclusão padrão. Eu não me importaria muito se ele é realizado com hashes ou qualquer outra coisa. Então porque não fazer uma classe conjunto que seria realmente ser implementado como um HashSet
nesta versão do C #, mas talvez um pouco diferente em uma versão futura?
Ou por que não, pelo menos ISet
interface?
Resposta ??h1>
Aprendidas Obrigado a todos que responderam abaixo: implementos ICollection
muito do que você esperaria de ISet
. Do meu ponto de vista, porém, implementos ICollection
IEnumerable
enquanto conjuntos não tem que ser enumeráveis ??--- exemplo: conjunto de números reais entre 1 e 2 (ainda mais, conjuntos podem ser geradas dinamicamente). Eu concordo que isso é um discurso retórico menor, como dos programadores normais "raramente precisam conjuntos incontáveis.
Ok, eu acho que eu entendi. HashSet
foi absolutamente feito para ser chamado Set
mas a palavra Set
é reservado em algum sentido. Mais especificamente, os criadores de .NET arquitetura queria ter um conjunto consistente (! Sic) das classes para diferentes idiomas. Isto significa que cada nome da classe padrão não deve coincidir com qualquer palavra-chave nas linguagens .NET. A palavra Set
, no entanto, é usado em VB.NET que na verdade é case-insensitive (é?) Por isso, infelizmente, não há espaço para manobra lá.
Mistério resolvido:)
Epílogo
A nova resposta por Alex Y. liga ao MSDN página que descreve o próximo .NET 4.0 interface de ISet
que se comporta muito bem como eu pensei que deveria e é implementado por HashedSet
. Final feliz.
Solução
(sua pergunta original sobre set
foi respondida. IIRC, "set" é a palavra com o maior número de diferentes significados no idioma Inglês ... obviamente isso tem um impacto no cálculo também.)
Eu acho que é bom ter HashSet<T>
com esse nome, mas eu certamente bem-vinda uma interface ISet<T>
. Dado que HashSet<T>
só chegou em .NET 3.5 (que em si foi surpreendente) Eu suspeito que pode eventualmente obter uma coleção mais completa de tipos baseada em conjunto. Em particular, o equivalente a LinkedHashSet
de Java, que mantém a ordem de inserção, seria útil em alguns casos.
Para ser justo, a interface ICollection<T>
realmente cobre a maior parte do que você quer em ISet<T>
, talvez isso não é necessário. No entanto, você poderia argumentar que o objectivo principal de um conjunto (que é principalmente sobre a contenção e apenas tangencialmente sobre ser capaz de interagir sobre os elementos) não é exatamente o mesmo que uma coleção. É complicado. Na verdade, um conjunto verdadeiramente matemático pode não ser iterable ou contável - por exemplo, você poderia ter "o conjunto dos números reais entre 1 e 2." Se você tivesse um tipo numérico de precisão arbitrária, a contagem seria infinito e Iterando sobre ele não faria qualquer sentido.
Da mesma forma a ideia de "adição" a um conjunto nem sempre fazem sentido. Mutabilidade é um negócio complicado ao nomear coleções: (
EDIT: Ok, respondendo ao comentário: a palavra-chave set
é de modo algum um legado para fazer com Visual Basic. É a operação que sets o valor de uma propriedade, vs get
que recupera a operação. Isto não tem nada a ver com a ideia de um conjunto como uma operação.
Imagine que em vez das palavras-chave foram realmente fetch
e assign
, por exemplo.
// Not real code!
public int Foo
{
fetch
{
return fooField;
}
assign
{
fooField = value;
}
}
é o propósito limpar lá? Agora, a real equivalente a isso em C # é apenas
public int Foo
{
get
{
return fooField;
}
set
{
fooField = value;
}
}
Então, se você escrever:
x = y.Foo;
que irá utilizar a parte get
da propriedade. Se você escrever:
y.Foo = x;
que irá utilizar a parte set
.
Isso é mais claro?
Outras dicas
Não há Set<T>
. Este BCL equipa Blog pós tem muito de detalhes sobre HashSet incluindo uma discussão não é totalmente conclusivo sobre incluindo de hash no nome. Eu suspeito que nem todos na equipe BCL gostou da decisão de usar o nome HashSet<T>
.
set
é uma linguagem C # palavra-chave que tem sido em torno desde a versão 1.0. Está é usado para definir a parte da atribuição de valor de uma propriedade (e get
é usado para implementar a parte de leitura de valor de uma propriedade). Neste contexto, você deve entender a palavra 'set' como um verbo, como em definir um valor.
HashSet<T>
é um implmentation particular do conceito matemático de um conjunto. Ele foi introduzido pela primeira vez em NET 3.5. Este blog pela equipe de BCL explica mais sobre o raciocínio por trás dele, assim como algumas pistas para por que o nome é HashSet<T>
e não apenas Set<T>
: http://blogs.msdn.com/bclteam/archive/2006/11/09/introducing-hashset-t -kim-hamilton.aspx .
No caso de HashSet<T>
você deve entender a palavra 'set' como um substantivo.
Set é uma palavra-chave reservada no VB.NET (é o equivalente ao conjunto em C #). VB.NET pode usar classes / métodos / etc com o mesmo nome como palavras-chave, mas eles têm de ser escrito entre colchetes, o que é feio:
Imports Wintellect.PowerCollections 'PowerCollections contains a class called Set'
Public Class Test
Private _myValue As Integer
Public Property MyValue() As Integer
Get
Return _myValue
End Get
Set ' Set as keyword'
_myValue = value
End Set
End Property
Public Function X As [Set](Of Integer)
Dim a As New [Set](Of Integer) ' Set as class'
Return a
End Function
End Class
Ah certo Eu entendo a sua pergunta agora
Não tenho certeza que posso 100% ver a necessidade de um ISet<T>
.
Eu acho que a questão é o que você vê como um comportamento essencial para um conjunto
Trata-se de adicionar, remover Contém etc. Se sim, então já ICollection<T>
fornece uma interface para isso.
Se é operações de conjunto, como Union, Intersect, etc, então é algo que você consideraria bastante genérico para fora abstrato a um enforcement estilo contrato?
Eu tenho que dizer que eu não sei a resposta certa para esta - Eu acho que é aberta ao debate e eu suspeito que a equipe BCL pode acabar colocando algo como isto em uma versão futura, mas isso é com eles. Eu pessoalmente não vê-lo como peça que falta maciça de funcionalidade
Original Publicar
O BCL não tem uma colecção de Set de todo, pelo menos não tanto quanto eu sei.
Há alguns 3o partido Set libs lá fora, como Iesi.Collections
HashSet<T>
foi introduzido no .NET 3.5 para criar um conjunto de coleta ou seja rápido onde você quer uma coleção sem duplicatas. Ele também tem operações de conjunto típicos, tais como União e Unir.
Confira este link de equipe BCL em HashSet
Você gostaria tipicamente usá-lo onde antes você tinha que usar List<T>
e verificar se há duplicatas ao adicionar.
Adicionar itens a um HashSet<T>
também pode ser significativamente mais rápido do que List
Alguns detalhes adicionais:
Outro recurso interessante do HashSet é que não lançar uma exceção se você tentar adicionar um duplicá-lo simplesmente não consegue adicionar a entrada duplicada que poupa ter que colocar um monte de blocos try.catch em torno de cada add - Nice:)
Eu tenho certeza que não há nenhuma classe Set<T>
na BCL, pelo menos em .NET 3.5 (e não .NET 4.0 ou ele parece). O que você espera é a necessidade de tal classe um, de qualquer maneira?
HashSet<T>
é em si apenas uma estrutura de dados comum conjunto que utiliza códigos de hash (o método GetHashCode
de um objecto) para comparar os elementos. Isto é simplesmente uma maneira eficiente de implementar um tipo de conjunto. (Outros métodos de controlo da igualdade provavelmente teria um desempenho inferior.)