2015-03-12 2 views
4

Я хочу автоматизировать некоторые тесты, чтобы проверить способность программиста написать эффективный алгоритм. В этом примере алгоритм должен выполнять простой двоичный поиск в массиве int.Как я могу предотвратить использование некоторых определенных классов?

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

Примечание: Этот код загружается отражение в ограниченной области.

Простым способом реализации этого метода является, конечно, Array.BinarySearch(sortedArray, value) из библиотеки .NET. Но моя цель - проверить способность программиста самостоятельно генерировать код, так что задайте вопрос:

Как я могу предотвратить использование программистом функции класса Array?

+2

Вы, мужчина, не читаете код? –

+0

Сделайте строковый поиск, используйте простой парсер C# и проверьте его на вызов (например, с помощью ANTLR), используйте Roslyn для разбора кода, затем проверьте его на наличие вызова. –

+0

Вы можете пройти через ряд ухищрений, включая замену сборки .NET на целевой компьютер, шаг сборки компилятора, парсер SonarQube в вашей системе сборки. На самом деле, вы должны просто прочитать код. –

ответ

-1

Метод 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:
Take a look at this answer

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

Я хотел бы рассмотреть с помощью Аспект-ориентированного программирования.

В частности, я бы заказал PostSharp.

PostSharp предоставляет границы методов, которые позволяют отменить выполнение метода до его ввода.

Вот пример:

• OnEntry - Перед выполнением тела метода

• OnExit - всегда вызывается, когда метод выполняется выполнение, даже если произошла ошибка

• OnSuccess - Вызывается только тогда, когда выполняется метод, и не было исключений.

• OnException - вызывается только тогда, когда метод прекратил выполнение из-за необработанного исключения

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

+0

Почему я получил очковый вычет? –

Смежные вопросы