2010-06-25 5 views
1

특별한 클래스 인 WrappedDataTable이 있다고 말하면 각각 WrappedDataTable을 정확히 하나의 DataTable과 연결하고 싶습니다. 게다가, 주어진 DataTable에 대해 하나 이상의 WrappedDataTable이 존재하기를 원합니다. 나는 익숙해지는 것 때문에, 나는 추측 처음에는 매우 의심 생각 난사전에서 변경 가능한 객체를 키로 사용하는 것이 완전히 괜찮습니까?

public static class DataTableWrapper 
{ 
    private Dictionary<DataTable, WrappedDataTable> _wrappedTables; 

    static DataTableWrapper() 
    { 
     _wrappedTables = new Dictionary<DataTable, WrappedDataTable>(); 
    } 

    public static WrappedDataTable Wrap(this DataTable table) 
    { 
     WrappedDataTable wrappedTable; 
     if (!_wrappedTables.TryGetValue(table, out wrappedTable)) 
      _wrappedTables[table] = wrappedTable = new WrappedDataTable(table); 

     return wrappedTable; 
    } 
} 

:

는 동료가 내 WrappedDataTable를 캐시와 같이, 하나에 액세스하기 위해 공장 방법을 사용할 수 있습니다 제안 사전에있는 키는 변경 불가능한 유형이어야한다는 생각. 하지만 아마도 이것이 반드시 그런 것은 아닙니다. 빠른 테스트 결과 DataTable은 내용에 대한 수많은 수정 과정에서 일관된 해시 코드를 유지하는 것으로 나타났습니다. 따라서 Dictionary<DataTable, TValue>ContainsKey에 대한 올바른 값을 일관되게 반환 할 수있는 것으로 보입니다.

기본적으로 object.GetHashCode의 기본 버전이 모든 개별 개체에 대해 변함없는 값을 반환하는지 또는 내가 DataTable으로보고있는 내용이 환상인지 궁금합니다.

전자가 사실이라면

- 그리고 object.GetHashCode 잘 작동합니다 - 그것은 "키와 같은 불변적인 유형을 사용하는"것 같다 조언 정말에만 시나리오에 적용

  1. 당신은 할 객체의 평등을 원한다 참조 평등과 반대되는 값 평등 및/또는
  2. 형식 멤버를 기반으로하는 GetHashCode 구현이있는 사용자 지정 형식이 있습니다.

저에게는 현명한 의사가 있습니까?


UPDATE : 내 질문에 대답하기위한 존 소총에 감사합니다. 다른 뉴스에서 나는 약간의 파기를했고 IEqualityComparer<T>을 생각해 냈습니다. 이 결국 신원 비교를 제공합니다!

Imports System.Collections.Generic 
Imports System.Runtime.CompilerServices 

Public Class IdentityComparer(Of T As Class) 
    Implements IEqualityComparer(Of T) 

    Public Overloads Function Equals(ByVal x As T, ByVal y As T) As Boolean _ 
     Implements IEqualityComparer(Of T).Equals 

     Return Object.ReferenceEquals(x, y) 
    End Function 

    Public Overloads Function GetHashCode(ByVal obj As T) As Integer _ 
     Implements IEqualityComparer(Of T).GetHashCode 

     Return RuntimeHelpers.GetHashCode(obj) 
    End Function 
End Class 

이 예제 프로그램을 살펴 보자 :

를 - 그것을 체크 아웃 (번역 사소한 VB.NET 싫어하는 미안 해요, 난 그냥 그래서 제가 그것을 쓴 것은의 VB.NET 프로젝트를했다)
Dim comparer As IEqualityComparer(Of String) = New IdentityComparer(Of String) 

Dim x As New String("Hello there") 
Dim y As New String("Hello there") 

Console.WriteLine(comparer.Equals(x, y)) 
Console.WriteLine(comparer.GetHashCode(x)) 
Console.WriteLine(comparer.GetHashCode(y)) 

출력 :

 
False 
37121646 
45592480 

답변

2

이 고유 한 값을 반환 할 필요가 없습니다. 그것은 변함없는 것을 돌려 주어야만합니다 - 그것은 바로 object.GetHashCode입니다.

DataTableEquals 또는 GetHashCode을 덮어 쓰지 않는 한 기본적으로 개체 동일성을 나타냅니다. 즉, 개체가 변형되었는지는 중요하지 않습니다.

개인적으로 나는 어떤 유형에 대한 신분 평등을 제공 IEqualityComparer<T>의 구현을보고 싶어하지만, 우리는 우리 자신이 있음을 구현할 수 없습니다 - GetHashCode 이 경우 반환 것입니다 무슨 알아내는 방법이 없습니다 무시되지 않았다. (자바 표준 라이브러리에서이 기능을 가지고 있지만, .NET은하지 않습니다 GRR..)

편집 : 우트는 - object.ReferenceEqualsRuntimeHelpers.GetHashCode(), 우리는 쉽게 IdentityEqualityComparer<T>을 구현할 수 있습니다. 예!

+0

@ 존 : GetHashCodeBase와 비슷합니까? 나는 결코 자바를 한 적이 없다는 것을 인정한다. (노다 타임은 나의 첫 번째 진출이었고, 기여보다는 코드를 항상 보았다.) –

+0

@Jeff : 기본적으로 어딘가에 정적 메서드가있다. Java에서는'System.identityHashCode'입니다. –

+0

@Jon : 유용합니다. 'ToString'과'Equals'의 원래 구현을 다른 목적으로도 얻을 수 있다면 유용 할 것입니다. –

0

나는 잘 이해한다고 생각합니다. 사전에 객체를 저장하려면 해시 값에 영향을주는 특성이나 다른 객체와의 동등성에 대한 테스트가 불변이어야합니다. 그러한 것들에 영향을 미치지 않는 특성은 변경 될 필요가 없습니다.

관련 문제