首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止使用某些特定的类?

如何防止使用某些特定的类?
EN

Stack Overflow用户
提问于 2015-03-12 13:13:46
回答 2查看 192关注 0票数 4

我想自动化一些测试,以检查程序员编写高效算法的能力。在这个示例中,算法是在一个int数组中执行一个简单的二进制搜索。

代码语言:javascript
复制
public class ComplexityPractice
{
    public bool BinarySearch(int [] sortedArray, int value)
    {
        // to be implement 
    }
}

注意事项:此代码是通过反射加载在受限域中的。

实现此方法的最简单方法当然是来自Array.BinarySearch(sortedArray, value)库的.NET。但我的目标是检查程序员自己生成代码的能力,所以问题是:

如何防止程序员使用数组类中的函数?

EN

回答 2

Stack Overflow用户

发布于 2015-03-12 13:36:21

方法1:

检查代码是否有效,然后测试它是否包含不允许的方法调用,但必须忽略字符串文本。

但是,如果Reflection可用,这不会阻止用户按名称调用方法。

代码语言:javascript
复制
bool validCode = true;
string[] unallowedMethods = new string[] 
{
  "Array.BinarySearch",
  ...
};
string sourceCode = ...;
ICodeCompiler codeCompiler = ...;
CompilerResults results = codeCompiler.CompileAssemblyFromSource(parameters, sourceCode);
validCode = result.Errors.Count == 0;
if (validCode)
 foreach (method in unallowedMethods)
   if (sourceCode.Contains(method)))
   //improve this by checking if occurrence is not a string literal in program 
   {
      validCode = false;
      break;
   }

方法2:

测试一个方法是否使用Mono调用另一个方法:

看看这个答案

代码语言:javascript
复制
static class MethodDefinitionExtensions
{
    public static bool CallsMethod(this MethodDefinition caller, 
        MethodDefinition callee)
    {
        return caller.Body.Instructions.Any(x => 
            x.OpCode == OpCodes.Call && x.Operand == callee);
    }
}

class Program
{
    private static AssemblyDefinition _assembly = AssemblyDefinition.ReadAssembly(
        System.Reflection.Assembly.GetExecutingAssembly().Location);

    private static void Method1()
    {
        Method2();
    }

    private static void Method2()
    {
        Method1();
        Method3();
    }

    private static void Method3()
    {
        Method1();
    }

    private static IEnumerable<MethodDefinition> GetMethodsCalled(
        MethodDefinition caller)
    {
        return caller.Body.Instructions
            .Where(x => x.OpCode == OpCodes.Call)
            .Select(x => (MethodDefinition)x.Operand);
    }

    private static MethodDefinition GetMethod(string name)
    {
        TypeDefinition programType = _assembly.MainModule.Types
            .FirstOrDefault(x => x.Name == "Program");
        return programType.Methods.First(x => x.Name == name);
    }

    public static void Main(string[] args)
    {
        MethodDefinition method1 = GetMethod("Method1");
        MethodDefinition method2 = GetMethod("Method2");
        MethodDefinition method3 = GetMethod("Method3");

        Debug.Assert(method1.CallsMethod(method3) == false);
        Debug.Assert(method1.CallsMethod(method2) == true);
        Debug.Assert(method3.CallsMethod(method1) == true);

        Debug.Assert(GetMethodsCalled(method2).SequenceEqual(
            new List<MethodDefinition> { method1, method3 }));
    }
}
票数 -1
EN

Stack Overflow用户

发布于 2015-03-12 13:40:17

我会考虑使用面向方面的编程。

具体来说,我会查看PostSharp

PostSharp提供了方法边界,允许您在输入方法之前取消方法的执行。

下面是一个例子:

·OnEntry-在方法主体执行之前

·OnExit-在方法执行时总是调用,即使有错误

·OnSuccess-只有在执行方法时才调用,而且没有任何例外

·OnException-只有在方法由于未处理的异常而停止执行时才调用

http://www.postsharp.net/blog/post/Day-4-OnMethodBoundaryAspect

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29010789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档