反对课<t> .method </t>

时间:2014-12-26 10:20:20

标签: c# linq reflection

对我来说,这是一个棘手的问题。
首先,我将尝试解释我的情景,之后它将成为问题,耐心...... :-)
我正在开发一种编译器,所以我有一个共同的接口:

interface Command
{
    bool IsValid { get; }
    // ... another properties
}

基类:

class CommandBase<T>: Command where T : CommandBase<T>, new()
{
    public bool IsValid { get; set; }
    // ... another properties

    public static Command Create<T>()
    {
        return new T();
    }
}

通过这种布局,可以轻松创建新命令,只需创建如下的派生类:

class Command1 : CommandBase<Command1> { }
class Command2 : CommandBase<Command2> { }
... etc

我有一个&#34;口译员&#34;我有这样一个数组的类:

CommandsCache = new Func<Command>[]
{
    Command1.Create,
    Command2.Create
}

使用此数组,很容易找到哪些命令更适合使用LINQ:

var command = CommandsCache
    .Where(p => /* some checks */)
    .FirstOrDefault(p => p.IsValid);

这样我就可以破解很多支票代码。

现在我的问题是:我每次创建一个新的&#34;命令&#34;我怎么能不需要更新我的数组?

我刚到这里:

var commands = typeof(Command)
    .Assembly
    .GetTypes()
    .Where(p => p.IsClass)
    .Where(p => p.BaseType != null && p.BaseType.Name.StartsWith("CommandBase"));

很好,我得到的所有类型都是&#34; CommandBase&#34;推导。
但是如何调用&#34;创建&#34;说&#34; T&#34;是&#34;命令&#34;?

之一

2 个答案:

答案 0 :(得分:3)

我不知道为什么你声明一个静态的Create方法。您始终可以使用Activator.CreateInstanceType创建新实例。

我可以选择做你想做的事情

var commands = typeof(Command)
    .Assembly
    .GetTypes()
    .Where(p => p.IsClass)
    .Where(p => p.BaseType != null && p.BaseType.Name.StartsWith("CommandBase"));


var CommandsCache = new List<Command>();

foreach (var c in commands)
{
    CommandsCache.Add((Command)Activator.CreateInstance(c));
}

答案 1 :(得分:0)

使用你们的评论,我用完了:

CommandsCache = typeof(Command)
    .Assembly
    .GetTypes()
    .Where(p => p.IsClass)
    .Where(p => p.BaseType != null && p.BaseType.Name.StartsWith("CommandBase"))
    .Select(Activator.CreateInstance)
    .Cast<Command>()
    .ToArray();

我的基类不需要&lt; T> “附录”了...... :-) 谢谢大家!