【问题标题】:Generic Abstract Method通用抽象方法
【发布时间】:2016-10-21 19:19:04
【问题描述】:

我在尝试在其中创建一个抽象类和一个本质上是通用的方法时遇到了麻烦。

class GameRoomManager : MonoBehaviour {
    public GameRoom GetSomething(string s){
        //do things here
        return GameRoomvar;
    }
}

现在我有另一个类做类似的事情,但涉及不同的类

class PlayerManager : MonoBehaviour{
    public Player GetSomething(string s){
        //player related things here
        return Playervar;
    }
}

我想让 GameRoomManager 和 PlayerManager 类都继承自抽象类 Abs

class GameRoomManager : Abs{
    public override GameRoom GetSomething<GameRoom>(string s){
        return GameRoomvar;
    }
}

在哪里

public abstract class Abs{
    public T GetSomething<T>(string s);
}

我在寻找解决方案时看到了一些关于这个主题的答案,并且都建议抽象类本身是通用的。我不想让抽象类通用,因为我看到的例子会让我做class GameRoomManager : Abs&lt;GameRoomManager&gt;。但我希望该方法返回 GameRoom 类型,而不是 GameRoomManager。

我对泛型并不完全熟悉,所以如果我出错了,请指出正确的方向

【问题讨论】:

  • But I want the method to return type PQR, not XYZ 然后将PQR 设为通用参数。为什么泛型参数必须是类型本身?
  • 是的,我已经考虑过了。但是这个例子只适用于一种返回 T 的方法。现在如果我有另一种返回 U 类型的方法呢?我必须制作GG&lt;T, U&gt;,这对我来说似乎很愚蠢。就此而言,还不如根本不创建抽象类。还是有其他原因,或者有更好的解释为什么我应该按照你说的方式做以及如何做?
  • 如果你不需要抽象类,那么就不要创建抽象类。鉴于它没有实现的方法,它确实应该是一个接口,而不是一个抽象类,但即便如此,如果你不需要接口,也不要创建一个。如果您需要,请使用它。
  • 是的,这是有道理的。至于类型参数,我猜没有其他方法可以拥有 &lt;T,U&gt;
  • 示例代码太模糊,无法理解您在这里真正想要完成的工作。不知道是XY问题还是什么。以这种方式使用泛型对我来说毫无意义。您所完成的只是拥有两个类,它们的方法名称相同,但行为不同。如果 HIJ 和 PQR 继承自一个共同的基础,那么它会更有意义。但是你也不需要那里的泛型。

标签: c# generics abstraction


【解决方案1】:

您必须与PQRHIJ 有一些共同点,这些类才能使用通用方法。

A计划

通过接口连接事物。

public interface IPart
{
    // put things here that are common between Part and GameRoom
    int ID { get; }
}
public interface IAbs
{
    IPart GetSomething(string name);
}

public class GameRoom : IPart
{
    public int ID { get; set; }
}

public class GameRoomManager : IAbs
{
    GameRoom part;

    #region IAbs Members

    public GameRoom GetSomething(string name)
    {
        return part;
    }


    IPart IAbs.GetSomething(string name)
    {
        return GetSomething(name);
    }

    #endregion
}

public class Player : IPart
{
    public int ID { get; set; }
}

public class PlayerManager : IAbs
{
    Player part;


    #region IAbs Members

    public Player GetSomething(string name)
    {
        return part;
    }
    IPart IAbs.GetSomething(string name)
    {
        return GetSomething(name);
    }

    #endregion
}

B计划

使用具有泛型类型和接口的基类

public interface IItem
{
    // put things here that are common between Part and GameRoom
    int ID { get; }
}
public class GameRoom : IItem
{
    public int ID { get; set; }
}
public class Player : IItem
{
    public int ID { get; set; }
}


public interface IAbs
{
    IItem GetItem(string guid);
}
public abstract class Abs<T> : IAbs
    where T : IItem
{
    protected abstract T GetItem(string name);

    protected Abs(T item)
    {
        this.Item=item;
    }
    protected T Item { get; private set; }

    #region IAbs Members

    IItem IAbs.GetItem(string name)
    {
        return GetItem(name);
    }

    #endregion
}


public class GameRoomManager : Abs<GameRoom>
{
    public GameRoomManager(GameRoom room) : base(room)
    {
    }
    protected override GameRoom GetItem(string guid)
    {
        return Item;
    }
    public GameRoom GetRoom(string guid) { return GetItem(guid); }
}

public class PlayerManager : Abs<Player>
{
    public PlayerManager(Player player)
        : base(player)
    {
    }
    protected override Player GetItem(string guid)
    {
        return Item;
    }
    public Player GetPlayer(string guid) { return GetItem(guid); }
}

这里是一些示例用法:

class Program
{
    static void Main(string[] args)
    {

        List<IAbs> managers=new List<IAbs>();
        var pm=new PlayerManager(new Player() { ID=1001 });
        var gm=new GameRoomManager(new GameRoom() { ID=2050 });

        managers.Add(pm);
        managers.Add(gm);

        IItem part = managers[0].GetItem("0000");

    }
}

【讨论】:

  • 在您发布答案时更新了问题。为您添加了类名以使其更有意义
  • 我更新了答案。请评论这种方法可能无法满足您的要求,因为我不清楚您要追求什么。
  • 好的,更具体地说,GetSomething 将是 GetRoom(string guid),它将返回 GameRoom 类型的对象,对于玩家来说也是如此,它将是 GetPlayer(string guid)返回一个播放器
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2015-10-06
相关资源
最近更新 更多