首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取从抽象类继承并在属性中具有特定值的类的实例

获取从抽象类继承并在属性中具有特定值的类的实例
EN

Stack Overflow用户
提问于 2018-05-06 01:21:33
回答 2查看 454关注 0票数 3

我正在开发一个工厂,基于两个标准创建具体的实例:

1)类必须继承自特定的抽象类

2)类必须在重写的属性中具有特定值

我的代码如下所示:

代码语言:javascript
运行
复制
public abstract class CommandBase
{
    public abstract string Prefix { get; }
}

public class PaintCommand : CommandBase
{
    public override string Prefix { get; } = "P";
}

public class WalkCommand : CommandBase
{
    public override string Prefix { get; } = "W";
}

class Program
{
    static void Main(string[] args)
    {
        var paintCommand = GetInstance("P");
        var walkCommand = GetInstance("W");  

        Console.ReadKey();
    }

    static CommandBase GetInstance(string prefix)
    {
        try
        {            
            var currentAssembly = Assembly.GetExecutingAssembly();
            var concreteType = currentAssembly.GetTypes().Where(t => t.IsSubclassOf(typeof(CommandBase)) &&
                                                                     !t.IsAbstract &&
                                                                     t.GetProperty("Prefix").GetValue(t).ToString() == prefix).SingleOrDefault();

            if (concreteType == null)
                throw new InvalidCastException($"No concrete type found for command: {prefix}");

            return (CommandBase)Activator.CreateInstance(concreteType);
        }
        catch (Exception ex)
        {            
            return default(CommandBase);
        }
    }
}

我得到了一个错误:

{System.Reflection.TargetException: Object与目标类型不匹配。在System.Reflection.RuntimeMethodInfo.CheckConsistency(Object目标处)在System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj处,BindingFlags invokeAttr,活页夹,Object[]参数,CultureInfo文化)在System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj处,CultureInfo invokeAttr,活页夹,Object[]参数,CultureInfo文化)

EN

Stack Overflow用户

回答已采纳

发布于 2018-05-06 02:07:47

一种更简洁的方法是定义自己的属性来存储前缀。

代码语言:javascript
运行
复制
[AttributeUsage(AttributeTargets.Class)]
public class CommandAttribute : Attribute
{
    public String Prefix { get; set; }

    public CommandAttribute(string commandPrefix)
    {
        Prefix = commandPrefix;
    }
}

然后像这样使用它们:

代码语言:javascript
运行
复制
[CommandAttribute("P")]
public class PaintCommand : CommandBase
{}

[CommandAttribute("W")]
public class WalkCommand : CommandBase
{}

在反射中:

代码语言:javascript
运行
复制
static CommandBase GetInstance(string prefix)
{       
    var currentAssembly = Assembly.GetExecutingAssembly();
    var concreteType = currentAssembly.GetTypes().Where(commandClass => commandClass.IsDefined(typeof(CommandAttribute), false) && commandClass.GetCustomAttribute<CommandAttribute>().Prefix == prefix).FirstOrDefault();

    if (concreteType == null)
        throw new InvalidCastException($"No concrete type found for command: {prefix}");

    return (CommandBase)Activator.CreateInstance(concreteType);
}
票数 5
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50192150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档