Как указать объект, относящийся к одному классу, но не к определенному подклассу?
class A
{
}
class B : A
{
}
void method(A that is not a B argument) {}
void generic_method(generic_class<A that is not a B> generic_argument) {}
void params_method(params A that is not a B[] params_arguments) {}
Есть ли какой-либо синтаксический способ сделать это? я понимаю, что могу просто сделать
if(argument is B)
throw new ArgumentException("argument cannot be a B", "argument");
в начале первого метода и сделать это в foreach для второго и третьего, но мне интересно, есть ли какое-то ключевое слово или концепция ООП, которая улучшает это.
Ответы
Ответ 1
Похоже, вы пытаетесь выразить противоположность ограничения, например:
var Foo<T>() where T : SomeClass
Это сдерживает T
как SomeClass
или подкласс 1... но вы пытаетесь сделать это явно не T
.
Нет, боюсь, в С# такого ограничения нет.
1 Ну, по модулю предположения, что SomeClass
- это класс, который начинается с; это может быть интерфейс, со значением, которое вы, вероятно, ожидаете.
Ответ 2
В С# такого ограничения не существует, потому что это плохая идея, в частности ее нарушение Принцип подстановки Лискова (один из SOLID)
Подстановка - принцип в объектно-ориентированном программировании. В нем указано, что в компьютерной программе, если B
является подтипом A
, тогда объекты типа A
могут быть заменены объектами типа B
(т.е. Объекты типа B
могут быть заменены для объектов типа A
) без изменения каких-либо желательных свойств этой программы
Если ваша программа явно отклоняет объекты типа B
, то это явно нарушение LSP и сильное указание на неправильность полиморфизма - вероятно, B
не должно наследоваться от A
в первую очередь.
Ответ 3
Что-то вроде этого? Разумеется, интерфейс, по моему мнению, был бы лучше в этом случае:
public abstract class A1
{
//shared things for A and B
public string Hello()
{
return "hello!";
}
}
public class A : A1
{
}
public class B : A1
{
}
public void something(A foo)
{
var bar = ((A1)foo).Hello(); // says hello
}