我有一个关于c#中的泛型的问题我希望创建可以使用泛型类型调用的命令类,而不需要它:
public class Command : ICommand
{
private readonly Action<object> execute;
private readonly Predicate<object> canExecute;
private readonly Action<TClass> tExecute;
private readonly Predicate<TClass> tCanExecute;
public Command(Action<object> execute, Predicate<object> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public Command(Action<TClass> execute, Predicate<TClass> canExecute = null)
{
tExecute = execute;
tCanExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || (this.canExecute != null && this.canExecute(parameter));
}
public bool CanExecute<TClass>(TClass parameter)
{
return canExecute == null || (canExecute != null && canExecute(parameter));
}
public void Execute(object parameter)
{
this.execute(parameter);
}
public void Execute<TClass>(TClass parameter)
{
execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
所以我可以这样使用:
new Command(p => some instructions);
或
new Command<Class> (p => some instructions p.property)
问题是在这种情况下类实例总是需要&lt;&gt;中的泛型类型,我知道我可以将p转换为某些类型,如(Class)p,但只是想知道这是否可行?
答案 0 :(得分:1)
问题不在于创建通用实例 - 因为你总能这样做 - 但是你将如何统一操作命令。您是否能够使用一个命令特定于某种类型 T 的事实。
为了使这个工作,你将在某个时候不得不垂头丧气。我不知道有任何设计不需要垂头丧气。
所以,这个过程就像坚持ICommand
接口,它对泛型一无所知。其Execute
和CanExecute
将是所有来电者可用的唯一公共界面,他们只会收到object
。
interface ICommand
{
bool CanExecute(object param);
void Execute(object param);
}
然后,在通用Command<T>
中,您可以使用强类型变体接受T
,并且您可以向下转换param
。
class Command<T> : ICommand
{
public bool CanExecute(object param) =>
this.CanExecute(param as T);
public void Execute(object param) =>
this.Execute(param as T);
public bool CanExecute(T param) { ... }
public void Execute(T param) { ... }
}
这就是为你而烦恼的地方。在给定T
实例的情况下,您能保证参数的类型ICommand
是正确的吗?如果可以,那你就没事了。否则,你将有一个设计缺陷。
另请注意,在此解决方案中,我将Command
类绑定到泛型参数,而不仅仅是其中一个方法。如果您只将CanExecute
和Execute
方法保留为通用,那么我预计以后会出现大问题 - 这类课程的覆盖面太大。使用通用命令,您可以自由地引入抽象Command<T>
或接口ICommand<T>
,然后为某些特定类型T
构建特殊命令,如:
class SaveCommand : ICommand<Document> { }
class CreateDirectory : ICommand<DirectoryInfo> { }
...
答案 1 :(得分:0)
我想,你可以制作Command&lt; T&gt; class as base and redefine
class Command : Command<Object> {}
用作非泛型。