检测不可重写的接口契约 [英] Detection of unrewritable interface contracts

查看:67
本文介绍了检测不可重写的接口契约的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,开发人员用一些行为实现基类,然后将其子类化。

I've run into a problem where developers implement a base class with some behaviour, then subclass it.

在子类中,他们然后添加一个自动消耗一些的接口基类中的属性。

In the subclass they then add an interface which automatically consumes some of the properties in the base class.

这意味着重写器没有添加ensure代码的目标。这在合同中留下了不容易识别的漏洞。

This means the rewriter does not have a target to add the ensures code. This leaves holes in the contracts that are not easily identified.

在这种情况下是否可以使重写器失败? (很高兴在代码合同选项卡上有一个选项)

Is it possible to make the rewriter fail in this case? (happy to have an option on the Code contract tab)

我还包含了检测代码,以显示实现接口的类何时不重新实现它们(这需要明确地扩展)实现接口)。

I've also included the detection code to show when classes that implement interfaces do not reimplement them (this needs to be extended for explicitly implemented interfaces).


namespace ConsoleApplication11
{
	[ContractClass(typeof(ContractIHeight))]
	public interface IHeight
	{
		int Height { get; }
	}

	[ContractClassFor(typeof(IHeight))]
	abstract class ContractIHeight : IHeight
	{
		public int Height
		{
			get
			{
				Contract.Ensures(Contract.Result<int>() > 3);
				return default(int);
			}
		}
	}

	[ContractClass(typeof(ContractIWidth))]
	public interface IWidth
	{
		int Width { get; }
	}

	[ContractClassFor(typeof(IWidth))]
	abstract class ContractIWidth : IWidth
	{
		public int Width
		{
			get
			{
				Contract.Ensures(Contract.Result<int>() > 3);
				return default(int);
			}
		}
	}

	class AbstractProgram
	{
		public int Height
		{
			get { return 3; }
		}
	}

	class Program : AbstractProgram, IHeight, IWidth
	{
		public void PreconditionFailure(int height)
		{
			Contract.Requires(height > 3);
		}

		public int Width
		{
			get { return 4; }
		}

		static void Main(string[] args)
		{
			var onMe = typeof(Program).GetInterfaces().Except(typeof(Program).BaseType.GetInterfaces());

			var p = new Program();
			var ap = p as IHeight;
			p.PreconditionFailure(ap.Height);

			var b = new Program().Width;
			var onProgram = typeof(Program).GetProperties(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
			foreach (var interfaceType in onMe)
			{
				var failures = interfaceType.GetProperties().Select(x => x.Name).Except(onProgram.Select(x => x.Name)).ToArray();
				if (failures.Length > 0)
				{
					Console.WriteLine("The following properties are defined in base classes; they need to be reimplemented in the same class the interface is added");
					Console.WriteLine(string.Join(Environment.NewLine, failures));
					Console.ReadLine();
				}
			}
		}
	}
}

推荐答案

优点。在这种情况下,我们应该只构成一个包含契约的方法,并调用基本方法。我会把它放在我们的TODO上。

Excellent point. We should in that case just make up a method that contains the contracts and just calls the base method. I'll put it on our TODO.

 


这篇关于检测不可重写的接口契约的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆