C #: ограничение типов в параметрах метода (не общие параметры) - PullRequest
9 голосов
/ 20 мая 2009

Я хотел бы закодировать функцию, подобную следующей

public void Foo(System.Type t where t : MyClass)
{ ... }

Другими словами, тип аргумента System.Type, и я хочу ограничить разрешенные Type s теми, которые получены из MyClass.

Есть ли способ указать это синтаксически, или t нужно проверять во время выполнения?

Ответы [ 6 ]

9 голосов
/ 20 мая 2009

Если ваш метод должен принимать тип Type в качестве аргумента, я не думаю, что есть способ сделать это. Если у вас есть гибкость в вызове метода, вы можете сделать это: public void Foo (MyClass myClass) и получить тип, вызвав .GetType ().

Чтобы немного расширить. System.Type является типом аргумента, поэтому нет способа дополнительно указать, что должно быть передано. Точно так же, как метод, который принимает целое число от 1 до 10, должен принимать целое число, а затем выполнять проверку во время выполнения, чтобы ограничения были должным образом соблюдены.

3 голосов
/ 20 мая 2009

Указывая тип быть MyClass или производным от него, является проверкой значения для самого аргумента. Это все равно что сказать привет параметр в

void Foo(int hello) {...}

должно быть между 10 и 100. Проверка невозможна во время компиляции.

Вы должны использовать универсальные шаблоны или проверять тип во время выполнения, как и любая другая проверка значения параметра.

2 голосов
/ 20 мая 2009

Вы можете использовать следующее:

public void Foo<T>(T variable) where T : MyClass
{ ... }

Вызов будет выглядеть следующим образом:

{
    ...
    Foo(someInstanceOfMyClass);
    ...
}
1 голос
/ 20 мая 2009

То, что вы хотите, теоретически может быть сделано с атрибутами. Но это намного яснее (имо) и делает то же самое:

public void Foo(MyClass m) {
   Type t = m.GetType();
   // ...
}
0 голосов
/ 20 мая 2009

Вы также можете использовать метод расширения, который будет доступен для всех объектов, конвертируемых в MyClass:

public static class MyClassExtensions
{
    public static void Foo(this MyClass obj)
    {
       // ...
    }
}

И вы можете использовать его, как если бы это был обычный метод объекта:

var x = new MyClass();
x.Foo();
0 голосов
/ 20 мая 2009

почему вы не используете

public void foo<t>();

вместо

...