How can I prevent the use of some specific classes?

I want to automate some tests to test a programmer’s ability to write an efficient algorithm. In this example, the algorithm should perform a simple binary search in an int array.

public class ComplexityPractice
{
    public bool BinarySearch(int [] sortedArray, int value)
    {
        // to be implement 
    }
}

Note . This code is loaded by reflection in the limited domain.

An easy way to implement this method is, of course, Array.BinarySearch(sortedArray, value)from the .NET library. But my goal is to test the programmer’s ability to independently create code, so the question is:

How can I prevent a programmer from using a function from the Array class?

+4
source share
2 answers

Method 1:

, , , , , .

, Reflection .

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 Cecil:

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

Aspect Oriented Programming.

, PostSharp.

PostSharp , .

:

• OnEntry -

• OnExit - , ,

• OnSuccess - , ,

• OnException - , -

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

-1

All Articles