实例化类型与字符串参数构造器,动态
我有以下代码:实例化类型与字符串参数构造器,动态
if (FileType == typeof(ScanUploadFile))
{
files.Add(new ScanUploadFile(filePath));
}
if (FileType == typeof(FaxFile))
{
files.Add(new FaxFile(filePath));
}
if (FileType == typeof(BulkScanFile))
{
files.Add(new BulkScanFile(filePath));
}
if (FileType == typeof(SpecialCategoryFile))
{
files.Add(new SpecialCategoryFile(filePath));
}
我怎样才能把它写不IF语句?
由于您只对构造函数感兴趣,所以可以使用:
Activator.CreateInstance(FileType, new string[] {filePath});
Activator
在System
库中定义。
使用Type
对象的GetConstructors
方法和选择的一个类型为字符串的单个参数,则调用它。
像这样:
private ConstructorInfo GetStringConstructor(Type type)
{
return (from ctor in type.GetConstructors()
let pars = ctor.GetParameters()
where pars.Length == 1 && pars[0].ParameterType == typeof(string)
select ctor).FirstOrDefault();
}
使用它,像这样:
var ctor = GetStringConstructor(typeof(Test));
if (ctor != null)
files.Add(ctor.Invoke(new string[] {filePath}));
我做了一个单独的方法提取的构造,但如果你只打算使用它实际上是创建一个实例,你可以重构它在同一个方法,它string
和Type
参数。尽管如此,请注意正确的错误处理。
但是,我会在这里考虑Factory method pattern,而不是只是在反射中立即潜水。我不知道它是否更适合您的需求,但似乎可能。
编辑:有人问津解释downvotes?我承认CreateInstance
更好,但我的方法具有更多的控制和更好的错误处理优势,所以我认为它至少应该在这里展示
我有反射的工作 - 谢谢。如果我使用工厂模式,我不会将IF语句移入工厂吗?我想工厂会像FileFactory一样,用一个名为GetFile(Type fileType,string filePath)的方法和我的问题中的IF语句。 – Anthony 2011-03-17 05:08:25
@Anthony:是的,但是然后交换机(或ifs)只会在一个地方(创建方法)。当你只需要改变一次以添加新类型时,这并不是什么大不了的事情。另外,反射并不便宜。我并不是说你必须过早地优化这样的东西,但反射也不会更易读,而ifs的即时处理会在编译时给你错误,而不是在运行时出错(没有找到合适的构造函数) )。底线是,即使您在创建方法中使用了反射,您也应该将其封装在类似工厂的东西中。 – Dyppl 2011-03-17 05:15:01
goog一个,我忘了'CreateInstance'具有参数 – Dyppl 2011-03-17 05:19:37
我用它在对象映射库一次过载。 :) – neontapir 2011-03-17 05:20:37
我用它,但我的最新项目,我想检查类型是否实际上有我需要的构造。这是使用'CreateInstance'的缺点 - 你有点希望正确的构造函数存在。在某些情况下,你无法确切地知道,并且突然间你正在做一些类似“异常编程”的事情,这很糟糕。 – Dyppl 2011-03-17 05:25:40