Существует почти наверняка лучший способ сделать то, что вы пытаетесь сделать. Если вы предоставите больше контекста, вы получите более полезные ответы.
Если вместо (или также) сделать ваши классы неявно скрытыми для строковых, вы также даете им переопределение ToString
, тогда вы можете сказать:
((KnownType)AClassBlah.ToString()).KnownFunc()
Однако вы получите исключение при попытке привести строку в KnownType
. Поэтому я должен спросить: почему вы пытаетесь пройти через string
в этой ситуации? Кастинги, как правило, отвратительная вещь, которая заставляет вас думать: «Может быть, мой дизайн нуждается в рефакторинге однажды». Это не то, что вы создаете в своей библиотеке классов в качестве рекомендуемого шаблона использования. Это низкоуровневое средство с предсказуемым поведением, поэтому нет способа (и нет веских причин предоставить способ) переопределить то, что делает явное приведение.
Update
Судя по вашему комментарию, вы смешиваете полиморфизм времени выполнения и статическое преобразование (время компиляции). Они не слишком хорошо смешиваются. Вы ранее пользовались языками с динамической типизацией? Похоже, что вы могли бы быть. Если у вас есть метод:
void FiddleWithObject(object obj)
{
// whatever
}
Тогда автор этого метода не знает во время компиляции, какие операции доступны в obj
. Поэтому они могут сказать:
void FiddleWithObject(object obj)
{
if (obj is IFiddly)
{
// Cool
obj.Fiddle();
}
else
throw new Exception("Wrong type of object");
}
Это затем взрывается во время компиляции для классов, которые не IFiddly
. Но в статически типизированном языке вы можете сказать:
void FiddleWithObject(IFiddly obj)
{
obj.Fiddle();
}
Это взорвется во время компиляции, если будет передан неправильный тип объекта, и вам не нужно ничего проверять во время выполнения. Меньше кода, ошибки найдены раньше ... насколько это аккуратно?
Функция неявного преобразования является частью перегрузки набора функций оператора. Все они очень привязаны к статическим типам. Они разрешаются во время компиляции на основе известного типа объекта. Так что, если вы не знаете фактический класс объекта, нет (встроенного) способа вызывать операторы на нем. Это просто не смешивается с динамической типизацией.
Если можно получить строку (например, «имя») из объекта IFiddly
, то вы можете сделать это свойством этого интерфейса:
public interface IFiddly
{
void Fiddle();
string Name { get; }
}
Или (как я уже отмечал ранее) вы можете просто переопределить ToString
для любого объекта, так как это метод virtual
в классе object
, от которого в конечном итоге наследуются все классы. Итак, сказав:
var str = someObject.ToString();
Вы будете вызывать реализацию ToString
, определенную в любом классе, someObject
является экземпляром.
В итоге:
- виртуальные и абстрактные методы и поддерживаемые интерфейсы: они предназначены для динамической типизации, времени выполнения и полиморфизма.
- оператор и неявная перегрузка преобразования (и обобщенные значения): они предназначены для статической типизации во время компиляции.
- броски отвратительны.