Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.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#_Factory_Builder_Strong Typing - Fatal编程技术网

C# 实现一个非泛型的静态工厂方法,从字符串输入创建各种泛型类(不使用“动态”类型)

C# 实现一个非泛型的静态工厂方法,从字符串输入创建各种泛型类(不使用“动态”类型),c#,factory,builder,strong-typing,C#,Factory,Builder,Strong Typing,我有一组从解析的XML中定义和填充的类 作为这项工作的一部分,我希望能够根据XML的指定动态实例化特定类型的集合类(在本例中,是为了管理/实例化异常) 我有一个类,大致定义如下: public class ExceptionGroup<T> : BaseCollectionClass<Exception> where T : Exception { // contents of this class don't really matter } public s

我有一组从解析的XML中定义和填充的类

作为这项工作的一部分,我希望能够根据XML的指定动态实例化特定类型的集合类(在本例中,是为了管理/实例化异常)

我有一个类,大致定义如下:

public class ExceptionGroup<T> : BaseCollectionClass<Exception> where T : Exception 
{
    // contents of this class don't really matter
}
public static dynamic CreateExceptionGroup( string exceptionTypeName )
{
    Type excType = DeriveType( exceptionTypeName );
    if ( !(excType is null) )
    {
        Type groupType = typeof( ExceptionGroup<> ).MakeGenericType( new Type[] { excType } );
        return Activator.CreateInstance( groupType );
    }
    return null;
}
使用这些类,我可以获取一个输入字符串,并最终得到一个从Exception类派生的已知、现有的C#Type类(假定输入字符串有效)。现在我想构建一个工厂方法,它可以创建新的
ExceptionGroup
对象,其中“T”是从原始字符串派生的对象类型

我通过使用
动态
类型作为工厂的返回类型来管理这一点,如下所示:

public class ExceptionGroup<T> : BaseCollectionClass<Exception> where T : Exception 
{
    // contents of this class don't really matter
}
public static dynamic CreateExceptionGroup( string exceptionTypeName )
{
    Type excType = DeriveType( exceptionTypeName );
    if ( !(excType is null) )
    {
        Type groupType = typeof( ExceptionGroup<> ).MakeGenericType( new Type[] { excType } );
        return Activator.CreateInstance( groupType );
    }
    return null;
}
公共静态动态CreateExceptionGroup(字符串exceptionTypeName)
{
类型excType=DeriveType(例外类型名称);
如果(!(excType为null))
{
Type groupType=typeof(组除外)。MakeGenericType(新类型[]{excType});
返回Activator.CreateInstance(groupType);
}
返回null;
}
不过,我对此感到非常不舒服,因为我不喜欢结果的模糊性/不确定性,也因为随后处理该结果可能会更麻烦/复杂。我更愿意更具体地指定返回类型,然后以某种方式适当地转换/限定它,例如(是的,我知道这是无效的!):

publicstaticexceptiongroup创建组(stringexceptiontypename)
{
类型excType=DeriveType(例外类型名称);
如果(!(excType为null))
{
类型[]类型=新类型[]{excType};
Type groupType=typeof(组除外)。MakeGenericType(类型);
return(ExceptionGroup)Activator.CreateInstance(groupType);
}
返回null;
}
…但是,当然,
例外组
在此语法/上下文中无效。(生成“CS7003:意外使用未绑定的泛型名称”),并且两者都不只是使用
ExceptionGroup
(生成:“CS0305:使用泛型类型'ExceptionGroup'需要1个类型参数。”)


那么,有没有一种方法可以通过其他语法或机制,通过更精确地描述结果的强(er)键入来实现这一点,或者使用
动态
,以及所有后续的相关开销,实际上是实现这一点的唯一方法?

,而我希望有一个更简单/简洁的解决方案(如果是的话,我很想看看!)Sweeper的一些回顾性提示让我意识到,通过注入一个新的抽象祖先类的开销,我基本上可以绕过这个问题:

public abstract class ExceptionGroupFoundation : BaseCollectionClass<Exception>
{
    public ExceptionGroupFoundation( object[] args = null ) : base( args ) { }

    // Implement necessary common accessors, methods, fields, properties etc here...
    // (preferably "abstract" as/when/where possible)
}
公共抽象类,GroupFoundation除外:BaseCollectionClass
{
public ExceptionGroupFoundation(对象[]args=null):基(args){}
//在这里实现必要的公共访问器、方法、字段、属性等。。。
//(如有可能,最好是“摘要”)
}
…然后从该类派生出我的泛型类:

公共类ExceptionGroup:ExceptionGroupFoundation其中T:Exception
{
公共例外组(对象[]args=null):基(args){}
//这门课的内容并不重要
}
…然后使用新的抽象类作为返回类型声明my factory方法:

public static ExceptionGroupFoundation CreateGroup( string exceptionTypeName )
{
    Type excType = DeriveType( exceptionTypeName );
    if ( !(excType is null) )
    {
        Type[] types = new Type[] { excType };
        Type groupType = typeof( ExceptionGroup<> ).MakeGenericType( types );
        return (ExceptionGroupFoundation)Activator.CreateInstance( groupType );
    }
    return null;
}
公共静态异常GroupFoundation CreateGroup(字符串异常TypeName)
{
类型excType=DeriveType(例外类型名称);
如果(!(excType为null))
{
类型[]类型=新类型[]{excType};
Type groupType=typeof(组除外)。MakeGenericType(类型);
return(例外GroupFoundation)Activator.CreateInstance(groupType);
}
返回null;
}

…基本上达到所需的结果,尽管有点麻烦/笨拙。

为什么
CreateGroup
不能是泛型的?你不知道调用
CreateGroup
时会得到什么类型的异常组吗?如果你知道,你可以指定你想要的异常类型作为泛型参数。如果你不知道,就不知道这里有两种情况。这可能不是类型安全的,也可能是类型安全的,但您总是会得到一个
ExceptionGroup
(因为您在编译时只知道这些)。这种情况取决于
ExceptionGroup
的内容。正如示例代码所示,当调用
CreateGroup
时,我所拥有的只是一个未知内容字符串。我甚至没有填充的类型类,更不用说在调用代码中指定泛型了……出于某种原因,C#能够理解这种需要/
Type-groupType=typeof中的公式(组除外)
上下文,但不在函数返回类型上下文中。那么告诉我,编译器究竟如何知道
ExceptionGroup
CreateGroup
返回的特定类型,并为您键入检查后续表达式?您最多只能在编译时获得
ExceptionGroup
的接口,assumi可以将
ExceptionGroup
的成员转换为协变接口。呃,同样的方法,大概是它在有效的
Type groupType=typeof(ExceptionGroup)
声明中实现的,和/或在泛型
where
声明中实现正确推断的相同方法(即
…其中T:Class
,此时编译器显然能够推断出“类”(在此上下文中)不仅包括“类”本身,还包括所有类派生类型).好的,我明白你的意思,但编译器不会自动执行此操作。你需要声明一个协变接口才能执行此操作。你是否能够为
的所有成员声明一个协变接口,除了组
,d
public static ExceptionGroupFoundation CreateGroup( string exceptionTypeName )
{
    Type excType = DeriveType( exceptionTypeName );
    if ( !(excType is null) )
    {
        Type[] types = new Type[] { excType };
        Type groupType = typeof( ExceptionGroup<> ).MakeGenericType( types );
        return (ExceptionGroupFoundation)Activator.CreateInstance( groupType );
    }
    return null;
}