views:

121

answers:

2

Hey, I'd like to know if what I'm trying to do is even possible? Comments in code should give and idea what I'm trying to achive :)

interface ITest<T> {
    T t { get; }
    bool DoTest();
}

public abstract class Test<T> : ITest<T> {
    public Test (T nt) {
        this.t = nt;
    }

    public Test () {
    }

    public T t {
        get;
        private set;
    }

    public abstract bool DoTest ();
}

public class STest : Test<string> {
    public override bool DoTest () {
    return true;
    }
}

public class ITest : Test<int> {
    public override bool DoTest () {
        return true;
    }
}

public class TestTest {
    // I don't want to specify type here, I'd like TestTest to be able to have
    // either a ITest or a STest. But for this class it should not matter.
    // I just want to use DoTest() later on. No matter what 
    // specialication of Test this is.
    Test myTest;
}

This might be a design problem, and I'd be willing to reconsider that if it is :)

+4  A: 

I would suggest extracting the DoTest method to a super-interface, like this:

interface ITestable
{
    bool DoTest();
}

interface ITest<T> : ITestable
{
    T t { get; }
}

public class TestTest 
{       
    ITestable myTest;
}

On an unrelated note, it is not recommended for class-names to begin with 'I' and for properties to begin with lower-case characters.

Ani
Yeah. It is also not recommended to call something `STest`/`ITest` when you could as well call it `StringTest`/`IntTest` and it would be a million times more readable.
Timwi
I don't think a particular naming convention is the most important aspect here.
Ondrej Tucny
@Ondrej: Nobody said it was *the* most important. However, anything that makes the code easier for us to understand can only benefit the OP.
Steven Sudit
A: 

Place the DoTest() method in a non-generic ITest interface. Also, I would recommend making the ITest interface have a non-generic version of t. This is a quite common approach seen with interfaces like IEnumerable and IEnumerable<T>. The advantage is the non-generic version doesn't get less-capable and can hence can be fully leveraged in places where no actual type parameter can be supplied.

interface ITest
{
    object t { get; }
    bool DoTest();
}

interface ITest<T> : ITest
{
    T t { get; }
}

Thanks to explicit implementation the unwanted non-generic or generic version (depending on the actual situation) can be hidden:

class STest : ITest<S>
{
    public string t { get; private set; }
    string ITest.t { get { return t; } }
    public bool DoTest { ... }
}
Ondrej Tucny