是否可以使用基于属性而不是类型的通用约束?
我正在尝试编写一个负责持久应用程序选项的类。由于需要保留选项,因此我发送的值必须是可序列化的。
最初我以为我能够编写一个具有如下签名的方法:
Public Sub SaveOption(Of T As ISerializable)(ByVal id As String, ByVal value As T)
或者如果您更喜欢 C#:
public void SaveOption<T>(string id, T value) where T : ISerializable
原则上这没问题,但是具有
属性的类型又如何呢? ?最值得注意的例子是 System.String,它没有实现 ISerialized,但显然它是我应该能够保存的类型。
那么,有没有一种方法可以根据类型的属性来限制在编译时方法中允许哪些类型?
I'm trying to write a class that will be in charge of persisting application options. Since the options need to be persisted the values that I'm sent must be serialisable.
Initially I thought I've be able to write a method with a signature like this:
Public Sub SaveOption(Of T As ISerializable)(ByVal id As String, ByVal value As T)
or if you prefer C#:
public void SaveOption<T>(string id, T value) where T : ISerializable
In principle this would be fine, but what about types that have the <Serializable>
attribute? The most notable example of this is System.String, it does not implement ISerializable
, but clearly it is a type that I should be able to save.
So, is there a way that I can restrict which types are allowed into a method at compiletime, based on their attributes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以对其他类型进行重载 - 以您的字符串为例:
但是;可串行化是......棘手的;我希望您必须在运行时检查这一点。
You could have overloads for the other types - taking your string example:
However; serializability is... tricky; I expect you're going to have to check this at runtime.
属性约束不会有太大作用,因为属性通常在编译时不提供任何保证,它们是运行时而不是编译器的信息。
在序列化情况下,
[Serializable]
属性仅指示您可以在运行时尝试序列化,而ISerialized
则保证您可以序列化它,因为您绝对可以调用GetObjectData
并且确保它做正确的事情是类的问题。例如,我可以拥有
,但
GoodClass
实际上并不比BadClass
好,因为我可以做EDIT: 属性也不是继承的,所以编译器无法确定在运行时传递的对象是否仍具有您所需的属性:
An attribute constraint wouldn't achieve much, since an attribute doesn't generally offer any guarantees at compile time, they're information for the runtime rather than the compiler.
In the serialization case, the
[Serializable]
attribute is only an indicator that you can attempt serialization at runtime, whileISerializable
guarantees that you can serialize it, because you can definitely callGetObjectData
and it's the class's problem to ensure that that does the right thing.For example, I can have
but
GoodClass
is really no better thanBadClass
, because I can doEDIT: Attributes also aren't inherited, so the compiler can't be sure that the object passed at runtime will still have the attribute you demanded:
没有。 :(
啊,不,实际上在 C# 4.0 中他们引入了代码契约。这应该可以在这里工作。
此链接的示例:CLR 4.0:代码合同
Nope. :(
Ah, no, actually in C# 4.0 they've introduced code contracts. That should work here.
Example from this link: CLR 4.0: Code Contracts
可以检查这一点,但你是对的,它必须在运行时完成,但比仅仅抛出异常更正式。
It is possible to check for this, but you're right, it will have to be done at runtime, but more formally than just throwing an exception.