是否可以将接口或类的派生或实现的IEnumerable部分声明为过时,而类或接口的其余部分仍然是最新的?我该如何声明?
interface Foo : IEnumerable<Bar>{
int SomethingNonObsolete{
get;
}
}
在上面的例子中,我希望使用已实现的IEnumerable的迭代器导致编译器 - 过时警告,而使用接口本身或使用SomethingNonObsolete
- 属性不会导致这样的警告。
以下代码应该指向编译器过时的警告
foreach(var bar in myFooImplementingInstance){
以下代码不应该指向编译器过时的警告
myFooImplementingInstance.SomethingNonObsolete.ToString()
更新
因为有很多答案,但每个答案只涉及问题的一部分,这里是摘要和最终陈述:
最后,由于LINQ,技术上不可能。
如果有人会使用它,正如Panda在他的回答中所说,这对于课程来说很容易。宣布调查员已经过时,你的罚款。
[Obsolete]
IEnumerator<Bar> GetEnumerator()
[Obsolete]
IEnumerator IEnumerable.GetEnumerator()
对于接口,它可以以类似的方式完成,如Bozhidar在评论中评论。使用new-keyword声明枚举器并将其标记为过时。
[Obsolete]
new IEnumerator<ITabularDataRow> GetEnumerator();
然而,虽然这两个版本一般都是他们应该做的,但是在使用LINQ时它们都会破坏。 因此,答案似乎是全面的方式是不可能的,并且这在大多数情况下是好的(参见MDeSchaepmeester的答案和评论)。
答案 0 :(得分:4)
在实施界面时,如下所示在Obsolete
方法中添加GetEnumerator
属性会产生您的期望:
public class MyClass : Foo
{
public int SomethingNonObsolete
{
get
{
throw new NotImplementedException();
}
}
[Obsolete]
public IEnumerator<Bar> GetEnumerator()
{
throw new NotImplementedException();
}
[Obsolete]
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
结果:
var c = new MyClass();
// Flagged as obsolete
foreach (var blah in c)
{
}
// Not flagged as obsolete
var s = c.SomethingNonObsolete;
答案 1 :(得分:2)
您可以使用ObsoleteAttribute
将成员标记为已过时。将它添加到每个过时的方法中,您将收到警告(或错误,具体取决于参数)。但是,这意味着您需要指定所有成员 - 除了实现Foo
的实例之外,这在您的情况下是不可能的。您唯一的另一个选择是将整个界面标记为过时,并将其替换为Foo2
- 事实上,这可能是解决此问题的最佳方式。
另请注意,这只会处理直接调用。编译器无法知道((IEnumerable<Bar>)yourFooInstance).GetEnumerator()
应该过时。
答案 2 :(得分:0)
这是一个有趣的情况,但您要做的是对您的API进行相当重大的更改。
Obsolete
主要用于提供替代,例如通过XML文档(例如,如果您使用SomethingNotObsolete
标记Obsolete
并说use SomethingNew instead
。
您要对API进行的更改将需要消费者进行代码重组,而不是简单地替换方法调用。因此,您应该(理想情况下)保留API的主要版本,并为您的消费者记录迁移路径。
我用一句话说的是Obsolete
在你的情况下在语义上是不正确的。
答案 3 :(得分:0)
您可以创建一个新界面。现在,在新界面中,您不会继承IEnumerable
并创建原始界面Obsolete
。现在,无论谁使用foreach(Foo f in myFooImplementingInstance)
都会收到你过时的消息。理想情况下,您还应添加一个提示,应该使用新接口。基本的想法是你的界面有一个唯一的目的。改变其继承链或类似方法将以极不可预测的方式破坏目的。因此,您应该创建一个提供新要求的新界面。
但是我同意@MDeSchaepmeester这是一个重要的重组,应该有详细记录。这样做将大量重新构建消费者代码,因此应该谨慎规划和实施。