C# 有没有办法访问泛型方法中T的新实例中的T.Method()?

C# 有没有办法访问泛型方法中T的新实例中的T.Method()?,c#,generics,C#,Generics,我有一个通用方法 class Program { Character CreateChar<T>() where T : new() { T DChar = new T(); Character Char = new Character { Name = DChar.Name, Health = DChar.Health }; return Char; }

我有一个通用方法

class Program {
    Character CreateChar<T>() where T : new() {
        T DChar = new T();
        Character Char = new Character {
            Name = DChar.Name,
            Health = DChar.Health
        };
        return Char;
    }
    public static void Main() {
        Character Char1 = CreateChar<Mage>();
    }
}
但是(这就像一个游戏)我有一些设置类型,比如“法师”

所以我的想法是制作一个通用方法“CreateChar”,这样我就可以像在Main中那样将Mage传递给它:

 Character Char1 = CreateChar<Mage>();
Character Char1=CreateChar();
但是,我似乎无法访问DChar.Name或DChar.Health,因为“t不包含“Health”的定义”。那么,有没有一种方法可以访问T方法?还是有更好的处理方法


事实上,现在我看到,“CreateChar();”也是无效的,因为“非静态字段需要对象引用”。所以我想我的问题是,出了什么问题,我该如何修复它?

您需要将
T
约束到包含要调用的方法的接口或基类

我想你看到的是工厂模式。这有用吗

public class Character 
{
    protected Character(string name, int health)
    {
        Name=name;
        Health=health;
    }

    public string Name { get; set; }
    public int Health { get; set; }
}

public class Mage : Character
{
    public Mage() : base("Evil Mage", 5)
    {
        this.Mana = 10;
    }

    public int Mana { get; set; }
}

public class Paladin : Character
{
    public Paladin() : base("Holy Paladin", 8)
    {
        this.Shield = 2;
    }

    public int Shield { get; set; }
}

public static class ChatacterFactory
{
    public static TChar Create<TChar>(string name) where TChar : Character, new()
    {
        var result = new TChar();
        result.Name = name;
        return result;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Mage mage = ChatacterFactory.Create<Mage>("Boom Mage");
        Paladin paladin = ChatacterFactory.Create<Paladin>("White Knight");
    }
}
公共类字符
{
受保护的字符(字符串名称,int-health)
{
名称=名称;
健康=健康;
}
公共字符串名称{get;set;}
公共int运行状况{get;set;}
}
公共职业法师:角色
{
公共法师():基础(“邪恶法师”,5)
{
这个。法力=10;
}
公共整数Mana{get;set;}
}
公共职业圣骑士:角色
{
公共圣骑士():基地(“神圣圣骑士”,8)
{
这个屏蔽=2;
}
公共整数屏蔽{get;set;}
}
公共静态类ChatacterFactory
{
公共静态TChar Create(字符串名),其中TChar:Character,new()
{
var结果=新的TChar();
result.Name=Name;
返回结果;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
Mage Mage=ChatacterFactory.Create(“Boom Mage”);
paladinpaladin=ChatacterFactory.Create(“白骑士”);
}
}

在泛型方法中,只能访问由
T
上的约束定义的方法(除非使用反射或类型检查/转换,这两种方法都不符合泛型的目的)。如果您将
T
约束为
字符
(我认为您必须这样做才能访问
Name
Health
),那么它应该可以工作(请发布带有相关属性的
字符
类)。但是为了给它传递一个
Mage
,你必须从
Character
继承
Mage

这就是我的意思;首先创建一个接口,定义所有字符将具有的属性(即所有公共属性、方法和事件):

然后我们可以创建一个名为
Character
的基类,该基类实现以下接口:

public class Character :  ICharacter
{
    public string Name { get; set; } = "Default Character";
    public int Health { get; set; } = 5;
    public string Description { get; protected set; } = "Default Description";
}
接下来,我们创建一些继承
character
类的字符类型:

public class Mage : Character
{
    public Mage()
    {
        Name = "Default Mage";
        Description = "Someone who uses or practices magic " + 
            "derived from supernatural or occult sources.";
    }
}

public class Elf : Character
{
    public Elf()
    {
        Name = "Default Elf";
        Description = "A supernatural creature of folk tales, " + 
            "typically represented as a small, elusive figure " + 
            "in human form with pointed ears, magical powers, " + 
            "and a capricious nature.";
    }
}
因此,现在我们可以将泛型类型
T
解析为
ICharacter
界面,并可以访问
Name
Health
属性:

class Program
{
    T CreateChar<T>() where T : ICharacter, new()
    {
        var result = new T();
        result.Name += " (created in 'CreateChar' method)";  // Modify a property
        return result;
    }

    // Rest of class omitted
}
类程序
{
T CreateChar(),其中T:ICharacter,new()
{
var结果=新的T();
result.Name+=“(在“CreateChar”方法中创建)”;//修改属性
返回结果;
}
//班上其他同学被省略了
}

如果我对你的理解正确,其中一个应该适合你:

//case 1

class Character1
{
    static Character1 CreateChar<T>(T character) where T : CommonGameCharecterClassOrInterface, new()
    {
        Character1 achar = new Character1
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}

class Character2
{
    static Character2 CreateChar(dynamic character)
    {
        Character2 achar = new Character2
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}

//case 2

class Character3
{
    static Character3 CreateChar<T>() where T : CommonGameCharecterClassOrInterface, new()
    {
        T character = new T();
        Character3 achar = new Character3
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}

class Character4
{
    static Character4 CreateChar<T>() where T : new()
    {
        dynamic character = new T();
        Character4 achar = new Character4
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}
//案例1
类别字符1
{
静态字符1 CreateChar(T字符),其中T:CommonGameChareClassorInterface,new()
{
Character1 achar=新字符1
{
Name=character.Name,
健康=性格。健康
};
返回achar;
}
}
类别字符2
{
静态字符2 CreateChar(动态字符)
{
Character2 achar=新字符2
{
Name=character.Name,
健康=性格。健康
};
返回achar;
}
}
//案例2
类别字符3
{
静态字符3 CreateChar(),其中T:CommonGameChareClassorInterface,new()
{
T字符=新的T();
Character3 achar=新字符3
{
Name=character.Name,
健康=性格。健康
};
返回achar;
}
}
类别字符4
{
静态字符4 CreateChar(),其中T:new()
{
动态字符=新的T();
Character4 achar=新字符4
{
Name=character.Name,
健康=性格。健康
};
返回achar;
}
}

Character void CreateChar()的声明应该是什么?那不会编译。请修正你的问题,使其有意义。请更具体地说明你正在尝试做什么。提供一个准确显示相关类型及其重要成员的好方法,解释您希望泛型方法做什么,为什么您认为它应该是泛型方法,到目前为止您尝试了什么,为什么它不起作用,以及您具体需要什么帮助。在泛型方法中,只能访问由
T
上的约束定义的方法(除非使用反射或类型检查/转换,这两种方法都不符合泛型的目的)。如果您将
T
约束为
字符
(我认为您必须这样做才能访问
Name
Health
),那么它应该可以工作(请发布带有相关属性的
字符
类)。但是为了给它传递一个
Mage
,你必须从
Character
继承
Mage
(或者,可能更好,让
Character
Mage
实现
ICharacter
,然后约束
T
,比如:
其中T:ICharacter
)@LardPies-
字符void CreateChar()
仍然无效。一个函数可以返回一个类型,也可以返回一个void,但不能同时返回两个。如果你的法师和其他游戏类没有继承一个共同的基类,你将无法从基因上处理这个问题。如果我对他的理解是正确的,问题是他不能自己编写CharClass
public class Mage : Character
{
    public Mage()
    {
        Name = "Default Mage";
        Description = "Someone who uses or practices magic " + 
            "derived from supernatural or occult sources.";
    }
}

public class Elf : Character
{
    public Elf()
    {
        Name = "Default Elf";
        Description = "A supernatural creature of folk tales, " + 
            "typically represented as a small, elusive figure " + 
            "in human form with pointed ears, magical powers, " + 
            "and a capricious nature.";
    }
}
class Program
{
    T CreateChar<T>() where T : ICharacter, new()
    {
        var result = new T();
        result.Name += " (created in 'CreateChar' method)";  // Modify a property
        return result;
    }

    // Rest of class omitted
}
//case 1

class Character1
{
    static Character1 CreateChar<T>(T character) where T : CommonGameCharecterClassOrInterface, new()
    {
        Character1 achar = new Character1
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}

class Character2
{
    static Character2 CreateChar(dynamic character)
    {
        Character2 achar = new Character2
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}

//case 2

class Character3
{
    static Character3 CreateChar<T>() where T : CommonGameCharecterClassOrInterface, new()
    {
        T character = new T();
        Character3 achar = new Character3
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}

class Character4
{
    static Character4 CreateChar<T>() where T : new()
    {
        dynamic character = new T();
        Character4 achar = new Character4
        {
            Name = character.Name,
            Health = character.Health
        };
        return achar;
    }
}