2016-02-22 3 views
0

Im совершенно новый для C# и задавался вопросом, возможно ли передать что-либо функции, которая не определена/различна каждый раз, как пример ниже;Функциональные параметры принимают все

string stringexam = "string" 

или

int intexam = 5; 

или

bool exam = false; 

и т.д ..

Myfunction(stringexam); 

Myfunction(intexam); 

Myfunction(exam); 

public static void MyFunction(accepteverything) { 

//DO SOMETHING 

} 

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

MyFunction(1,"ok example 1"); 
MyFunction(2, 22); 
MyFunction(3, false); 

Тогда я мог бы продолжить в MyFunction:

MyFunction(int method, accepteverything?!) 
{ 
    if(method == 1) { 
     ContinueExample1(string accepteverything); // CALLS FUNCTION CONTINUEEXAMPLE1 WHICH NEEDS A STRING AS PARAMETER 
    } 
    if(method == 2) { 
     ContinueExample2(int accepteverything); // CALLS FUNCTION CONTINUEEXAMPLE2 WHICH NEEDS A INT AS PARAMETER 
    } 
    if(method == 3) { 
     ContinueExample3(bool accepteverything); 
    } 
} 
+0

Вам нужно будет создать конструктор для каждой подписи. –

+2

Просто потому, что вы * можете * не означает, что вы * должны * – Brandon

+1

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

ответ

1

Вы также можете использовать общие функции. Это позволяет избежать бокс/распаковка слишком

public void MyFunction<T>(int method, T acceptEverything) 
{ 
    switch(method) 
    { 
     case 1: ContinueExample1(acceptEverything as string); //String parameter 
       break; 

     case 2: ContineExample2(Convert.ToInt32(acceptEverything)); //int parameter 
       break; 
     // etc. 
    } 
} 

вызов как этот

MyFunction(1,stringexam); 
MyFunction(2,intexam); 
+0

Это не собирается компилироваться, 'ContinueExample1' принимает' string' not 'T', поэтому вы собираетесь получить ошибка компилятора. Вы можете сделать «case 1: ContinueExample1 ((string) acceptEverything);' –

+0

@ScottChamberlain Исправить это – Viru

1

Если поведение метода не одно и то же, независимо от того, что тип передается, вы могли бы довольно легко сделать метод:

public void MyFunction(int method, object acceptEverything) 
{ 
    switch(method) 
    { 
     case 1: ContinueExample1(acceptEverything as string); 
       break; 

     case 2: ContineExample2(acceptEverything as int); 
       break; 
     // etc. 
    } 
} 

к сожалению, что собирается ввести много бокса и распаковки.

4

Вы можете сделать это с помощью перегрузок методов, с той же именованной функцией, но с разными типами параметров.

void MyFunction(string accepteverything) 
{ 
    ContinueExample1(accepteverything); 
} 
void MyFunction(int accepteverything) 
{ 
    ContinueExample2(accepteverything); 
} 
void MyFunction(bool accepteverything) 
{ 
    ContinueExample3(accepteverything); 
} 

Это позволяет сделать

string stringexam = "string" 
int intexam = 5; 
bool exam = false; 

MyFunction(stringexam); 
MyFunction(intexam); 
MyFunction(exam); 
0

Конечно, можно. Но вы, вероятно, хотите переосмыслить то, как вы идете. Желание сократить код, который вам нужно написать, хорошо.

Билл Гейтс - «Я выбираю ленивый человек, чтобы сделать тяжелую работу. Потому что ленивый человек найдет простой способ сделать это ».

Но это не всегда необходимо, и может ввести ненужную сложность к чему-то, что в противном случае просто и понятно.

Подумайте, что происходит в вашем коде. У вас есть экзамен, с которым вы хотите что-то сделать. Предположительно, вы обеспокоены тем, что может быть более одного способа идентифицировать данный экзамен для разных пользователей. Но, что бы вы ни хотели, вероятно, не изменится. Итак, давайте атакуем с этого угла: нам нужно будет определить экзамен с учетом неизвестного параметра.

public Exam FindExamFromAnything(object input) 
{ 
    int examID = 0; 
    if (int.TryParse(input.ToString(), out examID)) 
    { 
     return GetExamFromID(examID); 
    } 
    else 
    { 
     return GetExamFromName(input.ToString()); 
    } 

} 


public Exam GetExamFromID(int ID) 
{ 
    // get the Exam with the right ID from a database or something 
} 

public Exam GetExamFromName(string examName) 
{ 
    // get the Exam with the right name from a database 
} 

Теперь у вас есть метод, который вы можете передать, и вы вернете то, что искали. Большой!

За исключением ... Через два года кто-то есть список студентов, которые приняли данный экзамен, и пытается использовать метод:

List<string> students = new List<string> {"Alice","Bob"}; 
var exam = FindExamFromAnything(students); // nope! 

не работает. Но как он узнает? В подписи нет ничего, что указывало бы, что использовать в качестве объекта. Теперь он должен найти исходный код или использовать пробную версию и ошибку, чтобы выяснить, как использовать ваш API. Ваша документация может объяснить, что для нее требуется только int или строка, но ...

Вместо этого на самом деле не так много работы, чтобы написать второй метод. В качестве Scott Chamberlain points out вы можете перегрузить имя метода, чтобы принимать разные параметры. Лучшее решение для этой реализации должно стать более конкретным; Я частично отношусь к таким методам, как показано выше, то есть выставляйте свои GetExamFromString и GetExamFromID и все, что вам нужно, поэтому они сами объясняют.

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