简体   繁体   中英

using generic method in abstract class with child class result

I'm working to DRY some code up and I'm running into the following situation. I've reworked the code to provide a better example of the scenario.

namespace SourceCode
{
    public interface IFactory
    {
        public baseClass GenerateClass();
        public bool IsUsable();
    } 

    public abstract baseClass
    {
        ...
    }

    public AClass:baseClass
    {
        ...
    }

    public class FactoryA:IFactory
    {
        public baseClass GenerateClass()
        {
            return new AClass();
        }

        public bool IsUsable(){
        {
            return true if some condition;
        }
    }

    public BClass:baseClass
    {
        ...
    }

    public class FactoryB:IFactory
    {
        public baseClass GenerateClass()
        {
            return new BClass();
        }

        public bool IsUsable(){
        {
            return true if some condition;
        }
    }

    public static class FactoryProvider
    {
        List<IFactory> factories
        static FactoryProvider()
        {
            factories.Add(new FactoryA());
            factories.Add(new FactoryB());
        }

        static List<baseClass> GetClasses()
        {
            return (from f in factories where f.IsUsable() select f).ToList();
        }
    }
}

namespace SourceCode.Tests
{
    public class baseTests
    {
        public T GenericMethod<T>(){...}
    }

    public class ClassATests:baseTests
    {
        public void Test1()
        {
            ... generic used in a method provided by the base class
        }
    }

    public class ClassBTests:baseTests
    {
        public void Test1()
        {
            ... generic used in a method provided by the base class
        }
    }
}

So the problem in my tests is that there are tests that will have to happen for every child class.

UPDATE======================= I was able to solve my issue by doing the following.

namespace SourceCode.Tests
{
    public class baseTests<I> where I: baseClass
    {
        public void Test1()
        {
            var result = GenericMethod<I>();
            // The generic method will use ClassA for ClassATests
            // and ClassB for ClassBTests
        }

        public T GenericMethod<T>(){...}
    }

    public class ClassATests:baseTests<ClassA>
    {            
    }

    public class ClassBTests:baseTests<ClassB>
    {            
    }
}

Making your current A class generic could solve problems:

abstract class A
{
    // protected members...
    protected abstract A InternalGetData(List<A> src);

    public void SharedMethodHappensAlways()
    {
        List<A> src = new List<A>();
        var childResult = InternalGetData(src);
    }  
}

abstract class A<T> : A
    where T: A
{   
    public T GetData(List<A> src)
    {
        return src.OfType<T>().FirstOrDefault();
    }

    protected override A InternalGetData(List<A> src)
    {
        return GetData(src);
    }
}    

class B : A<B>
{    
}

class C : A<C>
{    
}

Sample usage:

List<A> src = new List<A>() { new B(), new C() };
B b = new B();
b.SharedMethodHappensAlways();
B firstB = b.GetData(src); // returns first instance of B
C firstC = new C().GetData(src);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM