简体   繁体   English

在C#中,如何拥有全局泛型类?

[英]In C#, how can you have a global generic class?

So I have a base set of abstract classes using BaseEngine namespace, and the real game project deriving the set. 因此,我有一个使用BaseEngine命名空间的抽象类的基础集,以及派生该类的真实游戏项目。

There are many base classes that have a set of abstract methods and predefined methods such as: Item, Entity, Skill 有许多基类具有一组抽象方法和预定义方法,例如:项目,实体,技能

public abstract class Item 
{
    public string name;
    public void DestroyItemInBaseEngine () 
    {
        // bunch of codes
    }
    public abstract void BakeItemTheWayYouWant ();
}

public abstract class SkillManager
{
    public abstract T InteractItemWithSkill<T> (T item)
        where T:Item, new(); //not sure if this particular line is valid, but this was written just to help you understand
}

And deriving classes such as: 和派生类,例如:

public class GameItem : Item
{
    public int variableSpecificToThisGameProject;

    // and other implementation for this specific game...
}

Now, Within BaseEngine, it would have abstract classes that refer Item multiple times in managers like BaseItemManager. 现在,在BaseEngine中,它将具有抽象类,这些抽象类在诸如BaseItemManager的管理器中多次引用Item。 Each game would manage differently so these managers must be derived as well. 每个游戏的管理方式都不同,因此也必须派生这些管理器。 When a specific game project derives BaseItemManager, it would have to use GameItem. 当特定游戏项目派生BaseItemManager时,它将必须使用GameItem。

BaseEngine was created to be able to be used with different projects, a basically set of abstract classes. 创建BaseEngine的目的是可以与不同的项目(基本上是一组抽象类)一起使用。

Every time when these derived objects are being referred in the game project, you either have to cast it, or use generic type in abstract methods like such: 每次在游戏项目中引用这些派生对象时,您要么必须强制转换它,要么在诸如此类的抽象方法中使用通用类型:

if (ValidateItemObject<GameItem> (GameItem item) != null)
    // do something with it

So because GameItem and other types are decided at compile time, is there anyway to declare something like T = GameItem, S = GameSkill for the entire project so we don't have to mention every time related methods (like above) or classes are called? 因此,由于GameItem和其他类型是在编译时决定的,因此整个项目是否都需要声明T = GameItem,S = GameSkill,因此我们不必在每次调用相关方法(如上述)或类时都提及?

I tried my best to make my case as clear as possible, but let me know if isn't clear what I'm trying to do. 我尽力使案件尽可能清楚,但如果不清楚我想做什么,请告诉我。

EDIT: 编辑:

protected abstract T ConvertTableToItem<T> (T item, LuaTable luaTable) where T:BaseItem;


protected override ProjectItem SetItemAPI<ProjectItem> (ProjectItem newItem, LuaTable luaTable)
{
    newItem.desc = "test";
}

This wouldn't work saying desc is not a member of the class. 说desc不是该类的成员,这是行不通的。 I can guarantee that it is. 我可以保证是这样。 desc (public string desc) is defined in ProjectItem. desc(公共字符串desc)在ProjectItem中定义。

ProjectItem is a derived class of BaseItem. ProjectItem是BaseItem的派生类。

If you want to declare a class with a fixed type parameter for a generic type, the simplest thing is to just inherit the generic type while specifying the type parameter you want. 如果要为泛型类型声明带有固定类型参数的类,最简单的方法是在指定所需的类型参数的同时继承泛型类型。 For example: 例如:

static class SomeSpecificClass : SomeBaseClass<GameItem> { ... }

Then any method in SomeBaseClass<T> that depends on the type parameter T can be called via SomeSpecificClass without specifying the type parameter T . 然后,可以通过SomeSpecificClass调用SomeBaseClass<T>中依赖类型参数T任何方法,而无需指定类型参数T

That said, the other tool in your toolbox that would probably address at least the example you provided is to take advantage of C#'s type inference for generic methods. 就是说,工具箱中的另一个可能至少解决您提供的示例的工具是利用C#的类型推断进行泛型方法的利用。

For example, if you have a base-class generic method like this: 例如,如果您有一个像这样的基类通用方法:

class SomeBaseClass
{
    public static T ValidateItemObject<T>(T item) where T : Item
    {
        // ...something
    }
}

Then you don't actually need to use the type parameter when calling the method, as long as the parameter you pass is correctly typed. 这样,只要正确键入传递的参数,实际上就不需要在调用方法时使用type参数。 For example: 例如:

GameItem gameItem = ...;

if (SomeBaseClass.ValidateItemObject(gameItem) != null)
{
    // ...something
}

(Naturally, if the code is in a class that inherits SomeBaseClass , then you don't actually need to specify the class name when calling the method). (自然,如果代码在继承SomeBaseClass的类中,则在调用该方法时实际上不需要指定类名)。

Unfortunately, your actual code example is fairly vague. 不幸的是,您的实际代码示例相当模糊。 But based on the comment to the question and your reply, it seems like the above should address your question. 但是根据对问题的评论和您的答复,以上内容似乎可以解决您的问题。 If not, please consider editing your question to provide a more specific, complete , but minimal code example , as well as a clear description of what that example does now, and how you would like it to change. 如果不是,请考虑编辑您的问题,以提供一个更具体, 完整 ,但最少的代码示例 ,以及对该示例现在的功能以及您希望如何更改的清晰描述。 You may also want to read https://stackoverflow.com/help/how-to-ask for tips on improving the clarity of the question. 您可能还想阅读https://stackoverflow.com/help/how-to-ask,以获得有关改善问题清晰度的提示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM