2016-06-14 5 views
0

으로 연장지도> I는 다음과 같이 정의 자바 제네릭 클래스가 있습니다자바 클래스 <? .NET

public static class KeyCountMap<T> 
{ 
    private Map<T, MutableInt> map = new LinkedHashMap<T, MutableInt>(); 
    // ... rest of the properties... 

    public KeyCountMap() 
    { } 

    @SuppressWarnings({ "unchecked", "rawtypes" }) 
    public KeyCountMap(Class<? extends Map> mapType) throws InstantiationException, IllegalAccessException 
    { 
     map = mapType.newInstance(); 
    } 
    //... rest of the methods... 
} 

을 나는대로 .NET에서 같은 클래스를 정의 :

public static class KeyCountMap<T> 
{ 
    private Dictionary<T, MutableInt> map = new Dictionary<T, MutableInt>(); 
    // ... rest of properties... 

    public KeyCountMap() 
    { } 

    public void KeyCountMap<T>(T obj) where T : Dictionary<T, MutableInt> 
    { 
     obj = new T(); // Unable to define new instance of T 
     map = obj;  // Unable to convert T to base class 
    } 
} 

그리고 방법은 정렬 정의 값이 내림차순으로 KeyCountMap<T> 인지도 이 메서드는 다음과 같이 정의됩니다.

public static KeyCountMap<T> SortMapByDescendValue<T>(KeyCountMap<T> _map) 
{ 
    List<KeyValuePair<T, MutableInt>> _list = new List<KeyValuePair<T, MutableInt>>(_map.EntrySet()); 
    // whereas _map.EntrySet() return of type HashSet<KeyValuePair<T, MutableInt>> 
    _list = _list.OrderByDescending(_x => _x.Value).ToList(); 

    KeyCountMap<T> _result = new KeyCountMap<T>(); 
    foreach (KeyValuePair<T, MutableInt> _entry in _list) 
    { 
     _result.Put(_entry.Key, _entry.Value); 
    } 
    return _result; 
} 

.NET에서 정의 된 클래스를 어떻게 수정합니까?

+0

이 기능의 목적은 무엇입니까? 해시 테이블/맵/사전은 순서를 보장하지 않습니다. * Java를 C#으로 자역하고 있습니까? 그렇다면 왜? – acelent

+0

예 프로젝트 요구 사항에 맞게 음역합니다. – maliks

+0

@acelent 답변에 댓글을 달았습니다. (받아 들여야합니다.) – maliks

답변

1

난 당신이 자바 (이 메타 데이터가 변수지만, 실제 개체가 제네릭 형식 정보의 무효) 컴파일 후 어떤 일반적인 유형 정보가 삭제 알고 가정합니다. 또한, 코드는 안전 입력되지 않은 : 당신이 Map의 비 매개 변수 인스턴스를 생성하고 있기 때문에 당신이 사용하고

@SuppressWarnings({ "unchecked", "rawtypes" }) 

.

. NET에서 일반 형식 정보가 으로 유지되고 런타임시이 사용되므로이 형식 시스템을 사용하지 마십시오.

것은의 당신의 C# 코드를 보자 :

public static class KeyCountMap<T> 

C#에서 정적 클래스는 인스턴스화 할 수없는 클래스, 그것은 혼자의 정적 멤버를 위해 사용됩니다. 나는 네가 이것을 원하지 않는다고 생각한다. 아마도 KeyCountMap은 내부 클래스와 달리 Java의 정적 중첩 클래스입니다.

C#에서는 내부 클래스가 없습니다. 중첩 클래스는 포함하는 클래스의 인스턴스와 데이터를 공유하지 않습니다. 마치 포함하는 클래스의 이름이 중첩 클래스의 네임 스페이스의 일부인 것과 같습니다. 따라서 여기에 static 키워드가 필요없고 실제로 원하지 않습니다.

{ 
    private Dictionary<T, MutableInt> map = new Dictionary<T, MutableInt>(); 

. NET에서 Dictionary은 클래스입니다.의도를 유지하려면 해당 인터페이스 인 IDictionarymap 필드의 유형으로 사용해야합니다.

// ... rest of properties... 

    public KeyCountMap() 
    { } 

    public void KeyCountMap<T>(T obj) where T : Dictionary<T, MutableInt> 

void 반환 형식이 생성자가 아닙니까?

C#에서 생성자는 일반 수 없습니다. 아마도 Type을 원할 것입니다.

귀하의 C# 코드는 여기 이해, 그렇게하지 않습니다 당신이 할 수있는 작업은 다음과 같습니다

public KeyCountMap(Type dictionaryType) 
    { 
     if (!typeof(IDictionary<T, MutableInt>).IsAssignableFrom(dictionaryType)) 
     { 
      throw new ArgumentException("Type must be a IDictionary<T, MutableInt>", nameof(dictionaryType)); 
     } 
     map = (IDictionary<T, MutableInt>)Activator.CreateInstance(dictionaryType); 
    } 
} 

우리는 인스턴스를 작성하기 전에 유형을 확인하고 있습니다. 우리가하지 않으면 인스턴스를 만들고 캐스트가 실패하고 할당이 수행되지 않을 것이므로 새 인스턴스는 그냥 쓰레기가됩니다.

실제 인스턴스가 프록시 일 수 있습니다. 그렇다면 인스턴스를 만들기 전에 유형을 확인하고 싶지 않을 수도 있습니다.


그냥 C#을 (또는 그 반대)로 자바를 복사 - 붙여 넣기하고 의 일부 정의, 작동 할 때까지 몇 가지 변경을 기대할 수는, 예를 들어, 작동 그것은 컴파일됩니다. 언어는 그렇게 유사하지 않으며, 너무 많은 미묘한 것들이 잘못되었다는 가능성이 있습니다.

이 접근법은 처음 엔 재미 있을지 몰라도, 너무 자주 걸려 넘어지면 곧 재미가 없어 질 것입니다. 코드를 한 줄씩 번역하기 전에 기본 언어를 배우고 대상 언어로 작업하는 방식을 이해해야합니다. 많은 경우 한 환경에서 수행해야하는 작업이 이미 다른 환경에 있거나 그 반대로 존재하거나 다른 작업에서 수행해야 할 작업이 많을 수도 있습니다.

이 특별한 경우 , Java는 Class을 일반 클래스로, .NET은 Type을 비 제너릭 클래스로 유지했습니다. .NET에서만 인터페이스와 델리게이트는 제네릭 형식 공분산 또는 반항을 나타낼 수 있습니다. 어쨌든 이것은 다소 제한적입니다. Type이 일반적인 경우 의도 된 용도는 공변 또는 반항이 될 수 있습니다. 그러나 Java에서 generic Class<T>은 런타임에 Class만큼 우수하다는 것을 기억하십시오. 컴파일시에만 가치가 있으므로 컴파일러에게 더 잘 알릴 수 있습니다.

+0

@ acelent - 오랜 설명에 감사 드리며,'KeyCountMap'은 Java의 중첩 클래스이므로, C# 코드의 중첩 클래스이기도합니다. – maliks

+0

당신의 생성자'nameof()'의 정의가 현재 컨텍스트에 존재하지 않습니다. – maliks

+0

* "당신의 생성자'nameof()'의 정의가 현재 컨텍스트에 없습니다"* - C# 6.0이고, 이전 버전에서는 "dictionaryType"입니다. – acelent

1

두 가지 문제가 있습니다. 먼저 T에 매개 변수없는 생성자가 있다는 것을 컴파일러에 알려야하므로 new T()을 호출 할 수 있습니다. 클래스 정의에 new() 인수를 제공하여이를 수행 할 수 있습니다.

또한 T가 실제로 할당하려는 사전 컴파일러에 알려, 그래서 우리가 조금 더 클래스 확장 할 수 있습니다 K가의 주요 유형입니다

public class KeyCountMap<K> 
{ 
    private Dictionary<K, MutableInt> map = new Dictionary<K, MutableInt>(); 
    // ... rest of properties... 

하는 것으로를 당신이 아직 지정하지 않은 사전.

두 번째로 T 일 수 있으며 다른 클래스는 T입니다. 그것을 생략하면 트릭을 수행 할 것입니다 :

public void Map() 
{ 
    var obj = new Dictionary<K, MutableInt>(); // Unable to define new instance of T 
    map = obj;  // Unable to convert T to base class 
} 
+0

이렇게하면 위에 정의 된 Java 클래스에서와 동일한 기능을 얻을 수 있습니까? – maliks

+0

자바 클래스가 정확히 그런 것은 아니지만 적어도 버그를 수정합니다. –

+0

메서드 매개 변수에서'T obj'를 제거 했으므로 메서드 정의에서'obj = new T();'를 어떻게 사용합니까? – maliks

0

어쩌면 이것이 무엇입니까?

public class KeyCountMap<T> 
    where T : new() 
{ 
    private Dictionary<T, MutableInt> map = new Dictionary<T, MutableInt>(); 
    // ... rest of properties... 

    public KeyCountMap() 
    { } 

    public KeyCountMap(T obj) 
    { 
     obj = new T(); 
     map = (Dictionary<T, MutableInt>)(object)obj; 
    } 
} 
+0

이 클래스의 Java 버전에서와 동일한 내용입니까? – maliks

+0

그리고 자바에서 클래스를 정적으로 선언하는 것은 어떨까요? – maliks

+0

@Taufel : 정적이라고 선언하여 달성하려는 목표는 무엇입니까? 나는 그것이 당신이 생각하는 것을하지 않는다고 생각한다 ... – Mehrdad