Можно ли ограничить тип именем метода?

Например, типы AA, BB и CC имеют метод Close(). Они не реализуют никакого интерфейса с void Close() в нем. Можно ли сделать ограничение типа на основе типа, имеющего метод Close?

public static void CloseThis<t>(this T openObject) where T : Closeable
{ openObject.Close();
}
</t>
3 ответа

Вы можете сделать что-то вроде этого:

class Abc
{ public void Close() { }
}
interface IClosable
{ void Close();
}
class AbcClosable : Abc, IClosable
{ }
class GenClosable<t> where T : IClosable
{ }
</t>

затем используйте

var genClosable = new GenClosable<abcclosable>();
</abcclosable>

или создать общий метод расширения

public static void CloseThis<t>(this T openObject) where T : Closeable
{ openObject.Close();
}
</t>

затем используйте его как

var abcClosable = new AbcClosable();
abcClosable.CloseThis();


Что касается меня, то решение должно основываться на агрегации не на наследовании. Зачем? "Это типы, которые я не могу редактировать". Я думаю, потому что этот тип принадлежит другому разработчику | company | etc, а наследование увеличивает связь, поэтому решение должно основываться на агрегации.

Обратите внимание, что любой из AA, BB или CC может быть sealed или может быть sealed

public sealed class Aa
{ public void Close() { }
}
public interface IClosable
{ void Close();
}
internal class AbcClosable : IClosable
{ private readonly Aa _aa; public AbcClosable(Aa aa) { _aa = aa; } public void Close() { _aa.Close(); }
}
public static class CloseableExtensions
{ public static void CloseThis<t>(this T value) where T : IClosable { value.Close(); }
}
</t>


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

static void CloseIfClosable(object o) { Type oType = o.GetType(); MethodInfo closeMethod = oType.GetMethod("Close"); if (closeMethod != null) { closeMethod.Invoke(o, new object[] { }); } }

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

licensed under cc by-sa 3.0 with attribution.