gpt4 book ai didi

c# - 实现一个非泛型的静态工厂方法以从字符串输入创建各种泛型类(不使用 "dynamic"类型)

转载 作者:行者123 更新时间:2023-12-04 08:23:42 26 4
gpt4 key购买 nike

我有一组从解析的 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 个类型参数。”)
那么,有没有办法通过一些其他的语法或机制,通过更精确的结果来使用强(er)类型,或者正在使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com