【问题标题】:How to write an interface for a generic method如何为泛型方法编写接口
【发布时间】:2015-01-09 08:11:23
【问题描述】:

我有 PlayersCollection 类,我想在 IWorldCollection 中连接它。 问题在于在界面中编写声明导致我出现此错误:

Assets/Scripts/Arcane/api/Collections/ItemsCollection.cs(17,22): error CS0425:
The constraints for type parameter `T' of method
`Arcane.api.ItemsCollection.Get<T>(int)
must match the constraints for type parameter `T' of
interface method `Arcane.api.IWorldCollection.Get<T>(int)'.
Consider using an explicit interface implementation instead

这是我的班级和我的界面。如何编写带有类约束的泛型方法实现?

public class PlayersCollection : IWorldCollection
{

    public Dictionary<Type, object> Collection;

    public PlayersCollection()
    {
        Collection = new Dictionary<Type, object>();
    }

    public T Get<T>(int id) where T: PlayerModel
    {
       var t = typeof(T);
       if (!Collection.ContainsKey(t)) return null;
       var dict = Collection[t] as Dictionary<int, T>;
       if (!dict.ContainsKey(id)) return null;
       return (T)dict[id];
    }
  }
}


public interface IWorldCollection
{
    T Get<T>(int id) where T : class;// Work when I change "class" to "PlayerModel".
}

非常感谢您的帮助:)

【问题讨论】:

    标签: c# generics interface


    【解决方案1】:

    在我看来,通过将泛型类型参数提升到类/接口级别,以下内容将满足要求:

    public class PlayersCollection<T> : IWorldCollection<T> where T : PlayerModel
    {
    
        public Dictionary<Type, T> Collection;
    
        public PlayersCollection()
        {
            Collection = new Dictionary<Type, T>();
        }
    
        public T Get(int id)
        {
           var t = typeof(T);
           if (!Collection.ContainsKey(t)) return null;
           var dict = Collection[t] as Dictionary<int, T>;
           if (!dict.ContainsKey(id)) return null;
           return (T)dict[id];
        }
      }
    
    public interface IWorldCollection<T> where T : class
    {
        T Get(int id);
    }
    

    如果我遗漏了要求中的某些内容,请告诉我。

    【讨论】:

    • 只是提示,您不需要每个 typeof(T) 的字典集合。在通用 PlayersCollection(T) 中,Collection 实例对于每个 T 都是唯一的,不会混淆。所以它可以简单地声明为Dictionary&lt;int, T&gt; Collection
    • @Will:谢谢;按照建议更新为Dictionary&lt;Type, T&gt; Collection
    【解决方案2】:

    我不确定你为什么需要这个界面,但也许这会有所帮助:

    public class PlayersCollection<T> : IWorldCollection<T> where T:PlayerModel
    {
    
    public Dictionary<Type, object> Collection;
    
    public PlayersCollection()
    {
        Collection = new Dictionary<Type, object>();
    }
    
    public T Get(int id)
    {
        ...
    }
    }
    
    
    
    public interface IWorldCollection<T> where T:class
    {
        T Get(int id);
    }
    

    【讨论】:

      【解决方案3】:

      试试这个:

      public class PlayersCollection : IWorldCollection<PlayerModel>
      {
      
          public Dictionary<Type, object> Collection;
      
          public PlayersCollection()
          {
              Collection = new Dictionary<Type, object>();
          }
      
          public PlayerModel Get<PlayerModel>(int id)
          {
              ///
          }
        }
      }
      
      
      public interface IWorldCollection<T>
      {
          T Get<T>(int id);
      }
      

      在您的情况下,在实现您的接口的类中,您为您的类添加了更多条件:

      • 界面中的where T : class
      • where T: PlayerModel在课堂上

      如果出于某种原因,您需要在接口中添加约束,则需要添加接口或基类,它们将被放置到接口声明中,并且您必须在 @ 中从它派生987654324@类,像这样:

      public abstract class Model
      {
      }
      
      public class PlayerModel : Model
      {
      }
      
      public interface IWorldCollection<T> where T : Model
      {
          T Get<T>(int id);
      }
      
      public class PlayersCollection : IWorldCollection<PlayerModel>
      {
          ///
      
          public PlayerModel Get<PlayerModel>(int id)
          {
              ///
          }
        }
      }
      

      【讨论】:

      • 谢谢你,但我必须保留 T Get(int id) 用于我的实现,因为此方法将返回 PlayerModel 的某个子类。
      • @DanielN 那么你应该遵循其他人的答案,并使你的 Collection 类也通用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 2010-09-09
      • 2012-03-01
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      相关资源
      最近更新 更多