[C#] Интерфейс vs. абстрактный класс

6yrop

Есть интерфейс IA внутри библиотеке (сборки). Наружу из сборки для интерфейса IA торчат только extention методы, методы самого интерфейса желательно скрыть внутри сборки. Первое, что приходит в голову заменить IA на абстрактный класс и методы объявить internal. Хотя в текущем коде это сделать можно, но класс вместо интерфейса может принести проблемы при дальнейшем развитии (нельзя указывать второй класс-наследник даже, если он полностью абстрактный).
Еще вариант ввести internal интерфейс
internal interface IInternalA: IA
{
  void Method1;
}
и внутри библиотеки кастить объекты IA к IInternalA, но тут неприятности каста получаем.
Как скрыть методы интерфейса внутри библиотеки? Какие-нибудь еще варианты есть? Или может вообще не скрывать? Но эти методы наверняка будут меняться при оптимизации библиотеки.

6yrop

или я не должен этого хотеть? тогда вопрос, почему?

kill-still

Умные люди говорят что лучше интерфейсом делать - так править проще. А потом при оптимизации можно легко поправить, если производительности не будет хватать.
З.Ы. А абстрактный класс генериком может быть? :confused:

timefim


public interface ITest
{
Something Something { get; set; }
}

public class Something { internal int Value {get;set;}}

public static class ITestExtension
{
public static int GetValue(this ITest test)
{
return test.Something.Value;
}
}

?

6yrop

Идею понял :D , полностью ли подходит посмотрю позже. Спасибо! :D

6yrop

да, все сработало :).
Замечания: получается несколько громоздко, поскольку пришлось дублировать интерфейсы ITest/ITestInternal, т.к. раньше был полифорфизм по интерфейсу ITest и его надо заменить полиформизмом по ITestInternal (делать наследников класса Something не хочется)
 

public interface ITest
{
Something Something { get; }
}

public class Something
{
private readonly ITestInternal testInternal;
internal Something(ITestInternal testInternal)
{
this.testInternal = testInternal;
}
internal string Method1
{
return testInternal.Method1;
}
}

internal ITestInternal
{
string Method1;
}

Но я думаю, эта громоздкость лучше, чем открытые методы.

6yrop

к сожалению, еще будут проблемы с ко/контрвариантностью, в C# 4.0 ко/контрвариантность вводится только для интерфейсов и для делегатов, а для классов нет :(

timefim

Код проблемы?

6yrop

я пока только читал про C# 4.0, поэтому могу ошибаться.
Здесь out можно поставить

public interface IValue<out T>
{
T GetValue;
}

А тут уже не получится

public interface IValue<T>
{
Provider<T> Provider { get; }
}

public class Provider<T>
{
internal T GetValue
{
}
}

timefim

только для интерфейсов и для делегато
Это где такое говорится?

6yrop

Limitations
Variant type parameters can only be declared on interfaces and delegate types, due to a restriction in the CLR. Variance only applies when there is a reference conversion between the type arguments. For instance, an IEnumerable<int> is not an IEnumerable<object> because the conversion from int to object is a boxing conversion, not a reference conversion.
http://code.msdn.microsoft.com/Project/Download/FileDownload...

timefim

Да, похоже этот подход перевести на вариантность будет проблематично .
Оставить комментарий
Имя или ник:
Комментарий: