获取Java'的行为;s级<;?扩展地图>;在.NET中

获取Java'的行为;s级<;?扩展地图>;在.NET中,java,c#,generics,inheritance,instantiation,Java,C#,Generics,Inheritance,Instantiation,我在java中有一个泛型类,定义为: public static class KeyCountMap<T> { private Map<T, MutableInt> map = new LinkedHashMap<T, MutableInt>(); // ... rest of the properties... public KeyCountMap() { } @SuppressWarnings({ "unch

我在java中有一个泛型类,定义为:

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...  
}  
公共静态类KeyCountMap
{
私有映射映射=新建LinkedHashMap();
//…其余的属性。。。
公钥countmap()
{ }  
@SuppressWarnings({“unchecked”,“rawtypes”})

public KeyCountMap(Class有两个问题。首先,您需要告诉编译器
T
有一个无参数构造函数,因此您可以调用
new T()
。您可以通过向类定义提供
new()
参数来实现这一点

您还必须告诉编译器,
T
实际上是您试图分配的字典,因此我们必须进一步扩展该类:

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

有两个问题。首先,您需要告诉编译器
T
有一个无参数构造函数,因此您可以调用
new T()
。您可以通过向类定义提供
new()
参数来做到这一点

您还必须告诉编译器,
T
实际上是您试图分配的字典,因此我们必须进一步扩展该类:

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

也许这就是你想要的

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;
    }
}
公共类KeyCountMap
其中T:new()
{
私有字典映射=新字典();
//…其他财产。。。
公钥countmap()
{ }
公钥计数映射(T obj)
{
obj=新的T();
map=(字典)(对象)obj;
}
}

也许这就是你想要的

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;
    }
}
公共类KeyCountMap
其中T:new()
{
私有字典映射=新字典();
//…其他财产。。。
公钥countmap()
{ }
公钥计数映射(T obj)
{
obj=新的T();
map=(字典)(对象)obj;
}
}

我假设您知道Java在编译后会删除任何泛型类型信息(变量有元数据,但实际对象没有泛型类型信息)。此外,您的代码不是类型安全的:

@SuppressWarnings({ "unchecked", "rawtypes" })
之所以使用此选项,是因为您正在创建
Map
的非参数化实例

在.NET中,您不能像这样绕过类型系统,因为泛型类型信息在运行时被保存并使用

让我们看看你的C代码:

在.NET中,
Dictionary
是一个类。为了保持目的,您应该使用
IDictionary
,即相应的接口,作为
映射
字段的类型

   // ... rest of properties...  

   public KeyCountMap()  
   { }  

   public void KeyCountMap<T>(T obj) where T : Dictionary<T, MutableInt>  
在创建实例之前,我们正在检查类型。如果不检查,我们将创建一个实例,强制转换将失败,分配甚至不会发生,因此新实例将是垃圾

实际实例可能是一个代理;如果是这样,您可能不想在创建实例之前检查类型


你不能只是把粘贴Java复制成C#(反之亦然),并期望在它工作之前只做一些更改,例如编译。这些语言不是那么相似,而且可能有太多微妙的错误

这种方法一开始可能很有趣,但你会经常绊倒,很快就不再有趣了。在开始逐行翻译代码之前,你应该学习基础知识,了解目标语言的工作方式。很多时候,你可能会发现在一种环境中必须做的事情在另一种环境中已经存在或者反之亦然,或者某件事在另一件事上或多或少需要采取步骤,等等


在这种特殊情况下,Java使
成为泛型类,而.NET保留了
类型
非泛型类。在.NET中,只有接口和委托可以声明泛型类型协变或逆变。这是相当严格的,如果
类型
是泛型的,则预期用途可以是协变或逆变riant。但请记住,在Java中,运行时的泛型
一样好,它只在编译时有任何值,您可以告诉编译器您更了解它,就像您所做的那样。

我假设您知道Java在编译后会删除任何泛型类型信息(有变量的元数据,但实际对象没有泛型类型信息)。此外,您的代码不是类型安全的:

@SuppressWarnings({ "unchecked", "rawtypes" })
之所以使用此选项,是因为您正在创建
Map
的非参数化实例

在.NET中,您不能像这样绕过类型系统,因为泛型类型信息在运行时被保存并使用

让我们看看你的C代码:

在.NET中,
Dictionary
是一个类。为了保持目的,您应该使用
IDictionary
,即相应的接口,作为
映射
字段的类型

   // ... rest of properties...  

   public KeyCountMap()  
   { }  

   public void KeyCountMap<T>(T obj) where T : Dictionary<T, MutableInt>  
在创建实例之前,我们正在检查类型。如果不检查,我们将创建一个实例,强制转换将失败,分配甚至不会发生,因此新实例将是垃圾

实际实例可能是一个代理;如果是这样,您可能不想在创建实例之前检查类型


你不能只是把粘贴Java复制成C#(反之亦然),并期望在它工作之前只做一些更改,例如编译。这些语言不是那么相似,而且可能有太多微妙的错误

这种方法一开始可能很有趣,但你会经常绊倒,很快就不再有趣了。在开始逐行翻译代码之前,你应该学习基础知识,了解目标语言的工作方式。很多时候,你可能会发现在一种环境中必须做的事情在另一种环境中已经存在或者反之亦然,或者某件事在另一件事上或多或少需要采取步骤,等等

在这种特殊情况下,Java使
Class
成为泛型类,而.NET使
Type
成为非泛型类。在.NET中,只有接口和委托可以声明泛型类型协方差或cont
   // ... rest of properties...  

   public KeyCountMap()  
   { }  

   public void KeyCountMap<T>(T obj) where T : Dictionary<T, MutableInt>  
   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);
   }
}