2015-09-16 2 views
2

Можно ли определить общее ограничение для нескольких классов, которые не используют базовый класс/интерфейс?Ограничение общего типа для значимых классов

Для примера.

class A 
{ 
} 

class B 
{ 
} 

class C 
{ 
    void Test<T>(T someObj) 
    { 
     ... 
    } 
} 

Я хочу передать класс А или В методу испытаний, ничего другого.

Я знаю, что могу установить оператор where с базовым классом/интерфейсом A или B, но я не могу указать базовый интерфейс/класс для связанных классов в моей ситуации.

+4

Нет, если вы поддерживаете только два типа без общего интерфейса, то ваш метод ISN 't generic, вместо этого используйте перегрузку. – Lee

+0

Согласитесь, просто используйте перегрузку метода. – Ric

+0

Короткий ответ: нет, вы не можете, нет конструкций типа «или» в общих типах, поэтому вы не можете сказать, где T: A или T: B. –

ответ

5

Нет, и это не имеет смысла для этого. Это уже не общий. Если класс A и B обмениваются свойствами, методами и т. Д., Они должны использовать один и тот же интерфейс или базовый класс. Если нет, они не являются «одинаковыми» и не могут рассматриваться как таковые.

Угадайте, что произойдет, если вы изменили подпись метода в одном из двух классов. Внезапно этот метод больше не «разделяется». Компилятор не пытается определить, какие методы и свойства можно считать разделяемыми, вместо этого он не поддерживает функцию, которую вы запрашиваете.

Опцией было бы использовать два метода (одна перегрузка каждого типа), которая вводит повторяющийся код, что плохо, конечно. Было бы лучше использовать interface, или если это действительно из ваших рук dynamic, хотя я стараюсь свести к минимуму его использование.

1

Это невозможно во время компиляции.

Если бы это было так, как бы вы использовали общий тип параметров T? Будет ли он вести себя как A или как B?

Рассмотрим следующий пример:

class A 
{ 
    public void MethodInA(); 
} 

class B 
{ 
    public void MethodInB(); 
} 

class C 
{ 
    // pseudocode here! 
    void Test<T>(T someObj) where T : A or B 
    { 
     // how it would behave if T is B? 
     someObj.MethodInA(); 
     // how it would behave if T is A? 
     someObj.MethodInB(); 
    } 
} 

Вместо извлечь некоторые базовый класс или интерфейс, который будет общим для обоих A и B классов и использовать его в общий метод ограничения.

1

Если нет ничего совместно, то:

void Test(A obj) {} 
void Test(B obj) {} 

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

private void TestImplementation<T>(T object) { ... } 
public void Test(A obj) { this.TestImplementation(obj); } 
public void Test(B obj) { this.TestImplementation(obj); } 
Смежные вопросы