简体   繁体   中英

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.

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. 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.

BaseEngine was created to be able to be used with different projects, a basically set of abstract classes.

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?

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. I can guarantee that it is. desc (public string desc) is defined in ProjectItem.

ProjectItem is a derived class of 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 .

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.

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. 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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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