2016-12-01 1 views
-1

Вот мой случай, у меня есть библиотека, которая имеет много методов и имеет одну точку входа. У меня нет доступа к исходному коду библиотеки.Изменение объекта, вызывающего метод, передается как делегат в C#

Библиотека имеет методы

Class A 
List<int> Methode1(int); 
List<int> Methode2(int); 
List<int> Methode3(int); 

У меня есть некоторый код, который выглядеть так:

T CallSomethingInLibrary<T>(T defaultValue, Func<int, T>funcLib, int input) 
{ 
    if(defaultValue==null|| globalFlagDataSourceAsGchanged==true) 
    { 
    defaultValue=funcLib(input) 
    } 
    return defaultValue; 
} 

Использование:

static A nameOfInstance = new A(); 
List<in> resultOfLib = CallSomethingInLibrary(defaultValue,nameOfInstance.Methode1,8); 

Проблема заключается в том, что я не хочу называть метод на ИИ хочет называть его в другом экземпляре. У меня есть глобальный список экземпляров, потому что количество объектов, которые говорят в библиотеке, ограничено до 10 одновременно. DefaultValue:

SemaphoreSlim Semaphore1 = new SemaphoreSlim(4); 

T CallSomethingInLibrary<T>(T defaultValue, Func<int, T>funcLib, int input) 
{ 
    if(defaultValue==null|| globalFlagDataSourceAsGchanged==true) 
    { 
    Semaphore1.Wait(); 
    A available=GetAvailableInstance(); 
    defaultValue=available.funcLib(input); 
    Semaphore1.Release(); 
    } 
    return defaultValue; 
} 

Я знаю, что я мог бы сделать это с Invoke, но мне нравится то, что я могу знать во время компиляции, если Methode1 является членом А и как хорошая подпись

И причина CallSomethingInLibrary существовать - это потому, что я не хочу копировать те строки, которые существуют.

if(DosomeValidation()) 
    { 
    Semaphore1.Wait(); 
    A available=GetAvailableInstance(); 
    ... 

Он также используется как некое обычное LazyInstantiation, которое делает больше.

Спасибо

+0

вы можете сделать 'Methode1' и другие' static', поэтому вам не нужна ссылка для их использования. –

+0

Можете ли вы прояснить вопрос и исправить исправленный код? Прямо сейчас вы смешиваете Methode1/methode1 (справедливо) и возвращаете типы. Список /int. Вы также игнорируете возвращаемое значение available.funcLib() во втором примере. Это поможет менее абстрактный (и несколько рабочий) пример. –

+0

@ M.kazemAkhgary У меня нет доступа к классу библиотеки A. – user3704628

ответ

1

Определите метод, как так:

T CallSomethingInLibrary<T>(Func<A, T> funcLib) 
{ 
    if(DosomeValidation()) 
    { 
     A available=GetAvailableInstance(); 
     funcLib(available); 
     //Where is the return here?? 
    } 
    else 
    { 
     return new List<int>() 
    } 
} 

А потом называют это так:

CallSomethingInLibrary(instance => instance.methode1(8)); 
0

Ваш "У меня есть некоторый код, которые выглядят как" не делает компиляции. Вы не можете вернуть new List<int>(), если тип возврата T. Вам также нужно что-то вернуть на ветке trueif.

Таким образом, чтобы сделать свой оригинальный код работы вам нужно что-то вроде этого:

T DoSomeValidation<T>(Func<int, T> funcLib, Func<int, T> funcDefault, int input) 
{ 
    if (DoSomeValidation()) 
    { 
     return funcLib(input); 
    } 
    else 
    { 
     return funcDefault(input); 
    } 
} 

Тогда вы бы назвать это как так:

A nameOfInstance = new A(); 
List<int> resultOfLib = CallSomethingInLibrary(nameOfInstance.methode1, n => new List<int>(), 8); 

Это работает.

Помимо этого, это немного запутывает то, о чем вы просите. Для вас тривиально вызывать эту функцию с другим экземпляром A. Было бы просто это:

A available = GetAvailableInstance(); 
List<int> resultOfLib = CallSomethingInLibrary(available.methode1, n => new List<int>(), 8); 

Там нет ничего в этом коде, который мешает вам называть это от любого типа - так долго, как компилятор может разрешить вызов вплоть до Func<int, T>.

Вам нужно уточнить, что вы подразумеваете под «Я хочу называть его в другом экземпляре».

+0

Я уточнил свой вопрос и объяснил, почему мне нужен такой код. спасибо – user3704628