#c# #interface #parameters
#c# #интерфейс #параметры
Вопрос:
Я уже знаю, что вы можете передать интерфейс в качестве параметра методу. Это позволяет указать только соответствующие члены объекта, требуемые методом. Что я хотел бы сделать, так это иметь возможность передавать тип интерфейса в качестве параметра.
Допустим, я объявил несколько интерфейсов, которые были неравномерно реализованы для ряда объектов, которые все образуют единый список / коллекцию. Могу ли я написать вспомогательный метод, который будет принимать как объект из списка, так и тип интерфейса в качестве параметра и проверять, реализует ли объект интерфейс? Следующий код, очевидно, является мусором, но он иллюстрирует то, что я хочу сделать:
private bool CheckType(object o, interface intrfce)
{
try
{
object x = (object)(intrfce)o;
return true;
}
catch (InvalidCastException e)
{
return false
}
}
На данный момент я просто планирую настроить перечисление для интерфейсов и потребовать, чтобы все классы предоставляли массив / список интерфейсов, которые они реализуют. Затем я могу просто проверить список перечислений, чтобы узнать, какие у них есть соответствующие интерфейсы (меня интересуют только созданные мной интерфейсы — я не после возврата IEnumerable
и ICloneable
т. Д.), Или я мог бы написать вспомогательные методы для каждого интерфейса. Мне просто было интересно, есть ли более элегантный способ сделать это?
Ответ №1:
Вы можете сделать это с помощью дженериков:
private bool CheckType<T>(object o) {
return o is T;
}
Вы называете это так:
foreach (object o in myList) {
if (CheckType<MyInterface>(o)) {
... // Do something
}
}
Учитывая, насколько легко это сделать, вы могли бы также сделать это в самом условном.
Наконец, если вы хотите обрабатывать только объекты, реализующие определенный интерфейс в смешанном списке, вы можете сделать это с OfType
помощью метода LINQ, например:
foreach (MyInterface o in myList.OfType<MyInterface>()) {
...
}
Комментарии:
1. Спасибо, именно то, что мне было нужно!
Ответ №2:
Вы можете сделать что-то вроде:
private bool CheckType(object o, params Type[] types)
{
//you can optionally check, that types are interfaces
//and throw exceptions if non-interface type was passed
if(types.Any(type => !type.IsInterface))
throw new Exception("Expected types to have only interface definitions");
return types.All(type => type.IsAssignableFrom(o.GetType()));
}
CheckType(new List<int>(), typeof(IEnumerable), typeof(IList)); //returns true
CheckType(0, typeof(IEnumerable)); //return false
Чтобы проверить последовательность объектов, вы можете использовать что-то вместе:
private bool CheckAllType(IEnumerable<object> items, params Type[] types)
{
return items.All(item => CheckType(item, types));
}
Комментарии:
1. Это очень полезно. Мне нравится возможность передавать несколько типов интерфейсов в качестве параметров. Спасибо!