作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一组从解析的 XML 定义和填充的类。
作为其中的一部分,我希望能够动态实例化特定类型的集合类,如 XML 指定的那样(在本例中,用于管理/实例化异常)。
所以我有一个类,大致定义如下:
public class ExceptionGroup<T> : BaseCollectionClass<Exception> where T : Exception
{
// contents of this class don't really matter
}
当我处理 XML 时,我将在字符串中包含异常派生类型的名称(即“ArgumentNullException”、“InvalidDataException”、“IndexOutOfRangeException”等),以及将使用的内容(消息)当/如果它被抛出时填充生成的异常(也是一个字符串)。
// Recursively determines if a supplied Type is ultimately derived from the Exception class:
public static bool IsException( Type type ) =>
(type == typeof( object )) ? false : (type == typeof(Exception)) || IsException( type.BaseType );
// Figures out if the specified string contains the name of a recognized Type
// and that the Type itself is genuinely derived from the Exception base class:
public static Type DeriveType( string name )
{
// If the string is null, empty, whitespace, or malformed, it's not valid and we ignore it...
if ( !string.IsNullOrWhiteSpace( name ) && Regex.IsMatch( name, @"^([a-z][\w]*[a-z0-9])$", RegexOptions.IgnoreCase ) )
try
{
Type excType = System.Type.GetType( name );
if ( IsException( excType ) ) return excType;
}
catch { }
// The type could not be determined, return null:
return null;
}
使用这些类,我可以获取一个输入字符串,并最终得到一个从 Exception 类派生的已知、现有的 C# Type 类(假设输入字符串是有效的)。现在我想构建一个可以创建新的工厂方法
ExceptionGroup<T>
对象,其中“T”是从原始字符串派生的对象类型。
dynamic
来解决这个问题。 type 作为工厂的返回类型如下:
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;
}
不过,我对此感到非常不舒服,既因为我不喜欢结果的模棱两可/不确定性,又因为随后处理该结果可能会更加麻烦/复杂。我宁愿更具体地指定返回类型,然后以某种方式适本地转换/限定它,例如(是的,我知道这是无效的!):
public static ExceptionGroup<> CreateGroup( string exceptionTypeName )
{
Type excType = DeriveType( exceptionTypeName );
if ( !(excType is null) )
{
Type[] types = new Type[] { excType };
Type groupType = typeof( ExceptionGroup<> ).MakeGenericType( types );
return (ExceptionGroup<>)Activator.CreateInstance( groupType );
}
return null;
}
...但是,当然
ExceptionGroup<>
在此语法/上下文中无效。 (生成“CS7003: Unexpected use of an unbound generic name”),也不是仅仅使用
ExceptionGroup
(生成:“CS0305:使用泛型类型 'ExceptionGroup' 需要 1 个类型参数。”)
dynamic
,以及所有后续相关的开销,实际上是实现此目的的唯一方法吗?
最佳答案
虽然我希望可能有一个更简单/简洁的解决方案(如果有的话,我很乐意看到它!)Sweeper 的一些回顾性提示让我意识到我可以通过注入(inject)一个新的抽象祖先的开销来基本上绕过这个问题类(class):
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)
}
...然后从那个派生我的通用类:
public class ExceptionGroup<T> : ExceptionGroupFoundation where T : Exception
{
public ExceptionGroup( object[] args = null ) : base( args ) { }
// contents of this class don't really matter
}
...然后使用新的抽象类作为返回类型声明我的工厂方法:
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;
}
...基本上达到预期的结果,尽管有些麻烦/尴尬。
关于c# - 实现一个非泛型的静态工厂方法以从字符串输入创建各种泛型类(不使用 "dynamic"类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65376383/
我是一名优秀的程序员,十分优秀!