Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用字符串参数将类型动态实例化到构造函数_C#_.net_C# 4.0 - Fatal编程技术网

C# 使用字符串参数将类型动态实例化到构造函数

C# 使用字符串参数将类型动态实例化到构造函数,c#,.net,c#-4.0,C#,.net,C# 4.0,我有以下代码: 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(filePat

我有以下代码:

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语句,我如何编写它呢?

使用
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
参数。不过要注意正确的错误处理

< > < <强> >,我会考虑这里,而不是仅仅在反射中跳水。我不知道它是否更适合你的需要,但它似乎很可能适合你


编辑:有人想解释投票失败的原因吗?我承认
CreateInstance
更好,但是我的方法有更多的控制和更好的错误处理的优点,所以我认为至少应该在这里介绍使用
类型
对象的
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
参数。不过要注意正确的错误处理

< > < <强> >,我会考虑这里,而不是仅仅在反射中跳水。我不知道它是否更适合你的需要,但它似乎很可能适合你


编辑:有人想解释投票失败的原因吗?我承认
CreateInstance
更好,但我的方法具有更多控制和更好的错误处理的优势,因此我认为至少应该在这里介绍它

因为您只对构造函数感兴趣,所以可以使用:

 Activator.CreateInstance(FileType, new string[] {filePath});

激活器
系统
库中定义。

由于您只对构造函数感兴趣,因此可以使用:

 Activator.CreateInstance(FileType, new string[] {filePath});

激活器
系统
库中定义。

我的反射功能正常-谢谢。如果我使用工厂模式,我会将If语句移动到工厂中吗?我认为工厂类似于FileFactory,有一个名为GetFile(Type fileType,string filePath)的方法和我问题中的IF语句。@Anthony:是的,但是开关(或ifs)将只位于一个位置(创建方法)。当您只需更改一次即可添加新类型时,这并不是什么大问题。此外,反射也不便宜。我并不是说您必须过早地优化这样的东西,但是反射也不是更具可读性,如果出现问题(没有找到合适的构造函数),使用ifs的实例化将在编译时而不是运行时给您带来错误。底线是,即使在创建方法中使用反射,也应该将其封装在类似于factory的东西中。如果我使用工厂模式,我会将If语句移动到工厂中吗?我认为工厂类似于FileFactory,有一个名为GetFile(Type fileType,string filePath)的方法和我问题中的IF语句。@Anthony:是的,但是开关(或ifs)将只位于一个位置(创建方法)。当您只需更改一次即可添加新类型时,这并不是什么大问题。此外,反射也不便宜。我并不是说您必须过早地优化这样的东西,但是反射也不是更具可读性,如果出现问题(没有找到合适的构造函数),使用ifs的实例化将在编译时而不是运行时给您带来错误。底线是,即使在创建方法中使用反射,也应该将其封装在类似工厂的东西中。Goog one,我忘了
CreateInstance
有一个参数重载,我曾经在对象映射库中使用过它。:)我也使用了它,但对于我的最新项目,我想检查类型是否实际具有我需要的构造函数。这就是使用
CreateInstance
的缺点-您有点希望存在正确的构造函数。在某些情况下,您无法确定,突然您正在执行类似“异常编程”的操作,这很糟糕。@Dyppl,这是非常正确的。如果在上面的示例中,FileType表示的类型不支持带字符串的构造函数,那么这种方法可能会变得混乱。Goog one,我忘记了
CreateInstance
有一个带参数的重载。我曾经在对象映射库中使用过它。:)我也使用了它,但对于我的最新项目,我想检查类型是否实际具有我需要的构造函数。这就是使用
CreateInstance
的缺点-您有点希望存在正确的构造函数。在某些情况下,您无法确定,突然您正在执行类似“异常编程”的操作,这很糟糕。@Dyppl,这是非常正确的。如果在上面的示例中,FileType表示的类型不支持带字符串的构造函数,那么这种方法可能会变得混乱。