C# 是否有泛型类型属性的替代解决方案?
因为,有什么替代方案吗?也许举个例子有助于讨论:C# 是否有泛型类型属性的替代解决方案?,c#,.net,generics,attributes,C#,.net,Generics,Attributes,因为,有什么替代方案吗?也许举个例子有助于讨论: public abstract class ErrorHandler { } public class AccessHandler : ErrorHandler { } public class ConnectionHandler : ErrorHandler { } public class OtherHandler : ErrorHandler { } public class CoHandler<T> : Attribute
public abstract class ErrorHandler { }
public class AccessHandler : ErrorHandler { }
public class ConnectionHandler : ErrorHandler { }
public class OtherHandler : ErrorHandler { }
public class CoHandler<T> : Attribute where T : ErrorHandler
{
public T GetHandler()
{
return default(T); // just an example
}
}
public enum Errors
{
[CoHandler<AccessHandler>()]
Access,
[CoHandler<ConnectionHandler>()]
Connection,
[CoHandler<OtherHandler>()]
Other
}
公共抽象类错误处理程序{}
公共类AccessHandler:ErrorHandler{}
公共类ConnectionHandler:ErrorHandler{}
公共类OtherHandler:ErrorHandler{}
公共类CoHandler:属性,其中T:ErrorHandler
{
公共T GetHandler()
{
返回默认值(T);//只是一个例子
}
}
公共枚举错误
{
[CoHandler()]
通道
[CoHandler()]
联系
[CoHandler()]
另外
}
好吧,您可以接受属性构造函数中的type或type name参数。比如说
[CoHandler(typeof(AccessHandler))]
或
前者使用起来更简单,而当您不想或不能依赖于包含类型的程序集时,后者很有用
顺便说一句,返回默认值(T)
将始终返回null,我希望它只是为了说明。以下是如何使用类型参数的示例:
public class CoHandler : Attribute
{
private Type _Type;
public CoHandler(Type type)
{
_Type = type;
// Use reflection to validate type argument to see if it has
// inherited from ErrorHandler and check if its has parameterless
// constructor
}
public ErrorHandler GetHandler()
{
return (ErrorHandler)Activator.CreateInstance(_Type);
}
}
您可以在属性构造函数中接受类型或类型名参数。比如说
[CoHandler(typeof(AccessHandler))]
或
前者使用起来更简单,而当您不想或不能依赖于包含类型的程序集时,后者很有用
顺便说一句,返回默认值(T)
将始终返回null,我希望它只是为了说明。以下是如何使用类型参数的示例:
public class CoHandler : Attribute
{
private Type _Type;
public CoHandler(Type type)
{
_Type = type;
// Use reflection to validate type argument to see if it has
// inherited from ErrorHandler and check if its has parameterless
// constructor
}
public ErrorHandler GetHandler()
{
return (ErrorHandler)Activator.CreateInstance(_Type);
}
}
在您的示例中,通过将枚举更改为类,并使用接口而不是属性,可以实现相同的功能 您可以使用as测试接口实现,还可以为接口编写扩展方法 您还可以在Errors类上实现方法,提供比普通旧枚举更多的范围
{
Errors error = Errors.Access;
var handler = error.GetHandler();
}
public abstract class ErrorHandler { }
public class AccessHandler : ErrorHandler { }
public class ConnectionHandler : ErrorHandler { }
public class OtherHandler : ErrorHandler { }
public interface CoHandler<T>
where T : ErrorHandler
{
T GetHandler();
}
public abstract class Errors
{
public static Errors Access = new AccessError();
public static Errors Connection = new ConnectionError();
public abstract ErrorHandler GetHandler();
private class AccessError : Errors, CoHandler<AccessHandler>
{
public override ErrorHandler GetHandler()
{
return new AccessHandler();
}
AccessHandler CoHandler<AccessHandler>.GetHandler()
{
return new AccessHandler();
}
}
private class ConnectionError : Errors, CoHandler<ConnectionHandler>
{
public override ErrorHandler GetHandler()
{
return new ConnectionHandler();
}
ConnectionHandler CoHandler<ConnectionHandler>.GetHandler()
{
return new ConnectionHandler();
}
}
}
{
Errors=Errors.Access;
var handler=error.GetHandler();
}
公共抽象类ErrorHandler{}
公共类AccessHandler:ErrorHandler{}
公共类ConnectionHandler:ErrorHandler{}
公共类OtherHandler:ErrorHandler{}
公共接口协处理器
其中T:ErrorHandler
{
T GetHandler();
}
公共抽象类错误
{
public static Errors Access=new AccessError();
public static Errors Connection=new ConnectionError();
公共抽象ErrorHandler GetHandler();
私有类访问错误:错误,共句柄
{
公共重写ErrorHandler GetHandler()
{
返回新的AccessHandler();
}
AccessHandler CoHandler.GetHandler()
{
返回新的AccessHandler();
}
}
私有类ConnectionError:错误,共同句柄
{
公共重写ErrorHandler GetHandler()
{
返回新的ConnectionHandler();
}
ConnectionHandler CoHandler.GetHandler()
{
返回新的ConnectionHandler();
}
}
}
在您的示例中,通过将枚举更改为类,并使用接口而不是属性,可以实现相同的功能
您可以使用as测试接口实现,还可以为接口编写扩展方法
您还可以在Errors类上实现方法,提供比普通旧枚举更多的范围
{
Errors error = Errors.Access;
var handler = error.GetHandler();
}
public abstract class ErrorHandler { }
public class AccessHandler : ErrorHandler { }
public class ConnectionHandler : ErrorHandler { }
public class OtherHandler : ErrorHandler { }
public interface CoHandler<T>
where T : ErrorHandler
{
T GetHandler();
}
public abstract class Errors
{
public static Errors Access = new AccessError();
public static Errors Connection = new ConnectionError();
public abstract ErrorHandler GetHandler();
private class AccessError : Errors, CoHandler<AccessHandler>
{
public override ErrorHandler GetHandler()
{
return new AccessHandler();
}
AccessHandler CoHandler<AccessHandler>.GetHandler()
{
return new AccessHandler();
}
}
private class ConnectionError : Errors, CoHandler<ConnectionHandler>
{
public override ErrorHandler GetHandler()
{
return new ConnectionHandler();
}
ConnectionHandler CoHandler<ConnectionHandler>.GetHandler()
{
return new ConnectionHandler();
}
}
}
{
Errors=Errors.Access;
var handler=error.GetHandler();
}
公共抽象类ErrorHandler{}
公共类AccessHandler:ErrorHandler{}
公共类ConnectionHandler:ErrorHandler{}
公共类OtherHandler:ErrorHandler{}
公共接口协处理器
其中T:ErrorHandler
{
T GetHandler();
}
公共抽象类错误
{
public static Errors Access=new AccessError();
public static Errors Connection=new ConnectionError();
公共抽象ErrorHandler GetHandler();
私有类访问错误:错误,共句柄
{
公共重写ErrorHandler GetHandler()
{
返回新的AccessHandler();
}
AccessHandler CoHandler.GetHandler()
{
返回新的AccessHandler();
}
}
私有类ConnectionError:错误,共同句柄
{
公共重写ErrorHandler GetHandler()
{
返回新的ConnectionHandler();
}
ConnectionHandler CoHandler.GetHandler()
{
返回新的ConnectionHandler();
}
}
}
但我将丢失where T:ErrorHandler
检查,对吗?有没有办法保持编译时检查?@Danny-是的,没错。您不能让编译器执行此检查。您可以使用静态分析工具(如FxCop)进行编译/构建时检查,然后编写自定义规则,但在我看来,这太麻烦了,您很可能会在第一轮测试中发现不正确的类型用法。但我将丢失where T:ErrorHandler
检查,对吗?有没有办法保持编译时检查?@Danny-是的,没错。您不能让编译器执行此检查。您可以使用静态分析工具(如FxCop)进行编译/构建时检查,然后编写自定义规则,但在我看来,这太麻烦了,您很可能会在第一轮测试中发现错误的类型用法。与上面的其他答案相比,这是最好的方法。与上面的其他答案相比,这是最好的方法。