c# - 转换为实现接口(interface)的通用抽象类

标签 c# generics

给定一个基类 Coin

public class Coin { }

和两个派生类Coin50CentCoin25Cent

public class Coin50 : Coin { }
public class Coin25 : Coin { }

任务是创建一个对象 CoinMachine (用于硬币交换,例如投入 50 美分硬币返回两个 25 美分硬币)对应以下要求:

  1. CoinMachine必须有两个 Coin25Cent 的集合和 Coin50cent对象。

  2. 集合必须派生自抽象泛型类 CoinStack<T>有两种方法

    void Push(T item); T Pop();

  3. CoinMachine必须按如下方式工作

    CoinMachine.Push(new Coin25()); // puts 25cent in 25c stack
    CoinMachine.Push(new Coin50()); // puts 50cent in 50c stack
    CoinMachine.Pop();      // gets 50cent from 50c stack
    CoinMachine.Pop();      // gets 25cent from 25c stack
    

这是我的实现 似乎我在抽象 CoinStack 类中有问题。

namespace ConsoleApplication1
{
    /* Given condition */
    class Program
    {
        static void Main(string[] args)
        {
            CoinMachine.Push(new Coin25());
            CoinMachine.Push(new Coin50());
            CoinMachine.Pop<Coin50>();
            CoinMachine.Pop<Coin25>();
        }
    }

    public class Coin { }
    public class Coin50 : Coin { }
    public class Coin25 : Coin { }
    /* End given condition */

    public interface ICoinStack
    {
        T Pop<T>();
        void Push<T>(T item);
    }

    /* The problem within this abstract class */
    public abstract class CoinStack<T> : ICoinStack
    {
        private Queue<T> _stack = new Queue<T>();

        public T Pop<T>() { return _stack.Dequeue(); }
        public void Push<T>(T item) { _stack.Enqueue(item); }
    }

    public class CoinStack50 : CoinStack<Coin50> { }
    public class CoinStack25 : CoinStack<Coin25> { }

    public class CoinMachine
    {
        private static Dictionary<Type, ICoinStack> map;

        static CoinMachine()
        {
            map = new Dictionary<Type, ICoinStack>()
            {
                { typeof(Coin50), new CoinStack50() },
                { typeof(Coin25), new CoinStack25() }
            };
        }

        public static T Pop<T>()
        {
            var type = typeof(T);
            return map[type].Pop<T>();
        }

        public static void Push<T>(T item)
        {
            var type = typeof(T);
            map[type].Push(item);
        }
    }
}

最佳答案

你的问题是ICoinStack具有通用方法,例如 Push<T>(T item) ,它基本上表示 ICoinStack 的实现可以接受 item 任何类型。

但是,在您的实现中CoinStack<T> , 你想限制 <T>ICoinStack.Push<T><T>CoinStack<T> .编译器应该已经给了你一个警告,说类型参数 T与类型参数同名 T外型。

你必须修复你的设计,或者通过制作 ICoinStack本身是通用的(如 ICoinStack<T> ),或更改它的方法以接受/返回 object (或者更好: Coin )而不是 T .

示例:

// accept/return Coin instead of T to keep ICoinStack
// and it's methods non-generic
public interface ICoinStack
{
   Coin Pop();
   void Push(Coin item);
}

// explicit interface implementation and the where T:Coin 
// constrain help us here to implement ICoinStack
public abstract class CoinStack<T> : ICoinStack where T:Coin
{
   private Queue<T> _stack = new Queue<T>();

   Coin ICoinStack.Pop() { return _stack.Dequeue(); }
   void ICoinStack.Push(Coin item) { _stack.Enqueue((T)item); }

   public T Pop() { return _stack.Dequeue(); }
   public void Push(T item) { _stack.Enqueue(item); }
}

// we need a cast in Pop<T>, and also the where T:Coin constrain
public class CoinMachine
{
   private static Dictionary<Type, ICoinStack> map;

   static CoinMachine()
   {
       map = new Dictionary<Type, ICoinStack>()
       {
           { typeof(Coin50), new CoinStack50() },
           { typeof(Coin25), new CoinStack25() }
       };
   }

   public static T Pop<T>() where T:Coin
   {
       var type = typeof(T);
       return (T)map[type].Pop();
   }

   public static void Push<T>(T item) where T:Coin
   {
       var type = typeof(T);
       map[type].Push(item);
   }
}

关于c# - 转换为实现接口(interface)的通用抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20372664/

相关文章:

Java 通配符有界泛型

c# - (如何)使用 Windows 文件资源管理器查找应用程序?

c# - 使用调度程序更新 WPF 进度条

c# - 泛型方法返回类型作为类型参数

java - 如何获取对当前类实例的编译时引用

c# - 我可以使以下 IQueryable linq 语句通用吗

vb.net - 在 vb.Net 中实现继承的泛型接口(interface)

c# - 强制 WaitCursor 到模态窗体的父窗体

c# - 提供者未返回ProviderManifestToken字符串 Entity Framework

c# - 如何在 Linq 查询中获取 'named' 元组组件?