Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Does this IConvertible interface satisfy the Interface Segregation Principle (ie. the "I" in SOLID)?

Here is the definition:

public interface IConvertible
{
    TypeCode GetTypeCode(); 
    bool ToBoolean(IFormatProvider provider);
    byte ToByte(IFormatProvider provider);
    char ToChar(IFormatProvider provider);
    DateTime ToDateTime(IFormatProvider provider);
    decimal ToDecimal(IFormatProvider provider);
    short ToInt16(IFormatProvider provider);
    int ToInt32(IFormatProvider provider);
    long ToInt64(IFormatProvider provider);
    sbyte ToSByte(IFormatProvider provider);
    float ToSingle(IFormatProvider provider);
    string ToString(IFormatProvider provider);
    object ToType(Type conversionType, IFormatProvider provider);
    ushort ToUInt16(IFormatProvider provider);
    uint ToUInt32(IFormatProvider provider);
    ulong ToUInt64(IFormatProvider provider);
}

So if I would like to have a class which will implements this IConvertible interface the I have to implement all of those methods, right? Or if I don't implement all of them, then I have to at least make an empty method or throw an Exception, right?.

In my opinion, the better way is to make more interface with fewer methods, for example:

public interface IConvertibleInt
{
        short ToInt16(IFormatProvider provider);
        int ToInt32(IFormatProvider provider);
        long ToInt64(IFormatProvider provider);
}

Or even:

public interface IConvertibleInt16
{
        short ToInt16(IFormatProvider provider);
}

public interface IConvertibleInt32
{            
        int ToInt32(IFormatProvider provider);
}

public interface IConvertibleInt64
{
        long ToInt64(IFormatProvider provider);
}

Is my reasoning correct?

share|improve this question
1  
Why has someone downvoted it, leaving no explanation? Looks like a legitimate question to me. –  Konrad Morawski Mar 23 at 12:47
    
Looks bad either way to me. Have you looked at how the Framework handles converters? –  david.pfx Mar 23 at 13:10
2  
Do you actually have an answerable question? “What do you think about this?” is not a question, it's requesting discussion, and this site is not a forum. “Do you know more examples?” Also isn't a question that's well suited for this kind of Q&A site. –  svick Mar 23 at 13:36
    
I take it the actual question is in the opening line. Does IConvertible violate Interface Segregation Principle? –  Konrad Morawski Mar 23 at 13:45
1  
@KonradMorawski: My guess would be that the downvoter was unhappy about, "Do you know more example interface which doesn't satisfy ISP ?" –  Brian Mar 23 at 19:47

2 Answers 2

up vote 6 down vote accepted

I like to interpret Interface Segregation Principle as

Interface should be closer related to the code that uses it than code that implement it. So the methods on the interface are defined by which methods client code needs than which methods class implements.

This implies that for each interface, there is always code that uses this interface. This is not the case of IConvertible. The interface itself doesn't make much sense. I also never saw property or function that was typed IConvertible, which empowers my claims. I even wonder how would code that only works on IConvertible looks and what would it do.

share|improve this answer

One difficulty with applying the Interface Segregation Principle in .NET is that any given storage location must have a single specified type. If there had been separate interfaces for IConvertibleToInt32, IConvertibleToInt64, then a type which only supported some of the conversions would only have to implement the ones it supported; code which needed exactly one conversion interface could accept a parameter of that type. Unfortunately, splitting things up in that fashion would make it difficult to write code which needs more than one conversion interface. For example, if a method needed to use IConvertibleToInt32, but which needed to pass an object to a method that needed IConvertibleToInt64, there would be no way to specify that it needed an object which supported both interfaces unless there were existed an interface which inherited from both and all types of interest which implement both interfaces also implement the composite one.

If .NET made had a means of defining a special kind of "composite" interface such that any class which implemented all of the components would automatically be regarded as an implementation of the composite, then it would make sense to subdivide interfaces much more finely. The lack of such ability, however, makes it necessary to define interfaces which are much coarser than would be ideal.

share|improve this answer
    
If .NET made had a means of defining a special kind of "composite" interface such that any class which implemented all of the components would automatically be regarded as an implementation of the composite - or duck typing, isn't it. Actually I believe generics could be put to a good use here, I'm thinking along the lines of IConvertible<F, T> (where F stands for from and T - the target type). Generics allow for type constraints, so perhaps this could be more flexible. –  Konrad Morawski Mar 26 at 9:28
    
@KonradMorawski: The best pattern I've found is interface ISelf<out T> { T self {get;} }. If all of the interfaces of interest include an extra parameter TExtra and inherit ISelf<TExtra>, one can sort of achieve composite interfaces, provided that every implementation of ISelf<anything> implements ISelf<itsOwnType>. One doesn't avoid typecasting, however, and if a reference is cast and assigned to variable x of type IFoo<IBar<IBoz>>>, then x will implement IFoo, x.self will implement IBar, and x.self.self will implement IBoz. For a class implementing the pattern... –  supercat Mar 26 at 15:13
    
...all three references will identify the same object, and one could cast x to IBar<IFoo> or any other desired permutation, but nothing would prevent someone from implementing a class where such behaviors wouldn't hold. What I'm asking for would be a bit like duck-typing, but a bit more formal and structured than typical duck-typing languages (since types that implement IFoo and IBar could only satisfy code that simply wants the combination, rather than code which demands a particular composite interface). –  supercat Mar 26 at 15:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.