Click here to Skip to main content
15,889,216 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have two intefaces:
C#
public interface ICopy<T>
{
    T GetCopy();
}
public interface IValid
{
    bool IsValid { get; }
}

and several classes and one interface which has nothing in common (I just simplified their names)
C#
public interface IObj: ICopy<IObj>, IValid {/*has other methods*/}
public class ObjA : ICopy<ObjA>, IValid {/*implementation*/}
public class ObjB : ICopy<ObjB>, IValid {/*implementation*/}
public class ObjC : IObj {/*implementation*/}
public class ObjD : ObjX, IObj {/*implementation*/}
public abstract class ObjX {/*some methods*/}

And I need some thing like
C#
public interface ICommon<T> : ICopy<T>, IValid { } //nothing more, it's empty

so I could create some list extention where list item is of type that implements both ICopy and IValid interfaces
C#
public static List<T> GetChanged<T>(this List<T> src) where T : ICommon<T>
{
    return src
        .ConvertAll(x => x.GetCopy())
        .Where(x => x.IsValid).ToList();
}

As a result I want to decrease code amount following DRY pr.
C#
public interface IObj: ICommon<IObj> {/*has other methods*/}
public class ObjA : ICommon<ObjA> {/*implementation*/}
public class ObjB : ICommon<ObjB> {/*implementation*/}
public class ObjC : IObj {/*implementation*/}
public class ObjD : ObjX, IObj {/*implementation*/}
public abstract class ObjX {/*some methods*/}

C#
List<ObjA> a = new();
List<ObjB> b = new();
List<ObjC> c = new();
List<ObjD> d = new();

C#
// before
a = a.ConvertAll(x => x.GetCopy())
    .Where(x => x.IsValid).ToList();

b = b.ConvertAll(x => x.GetCopy())
    .Where(x => x.IsValid).ToList();

c = c.ConvertAll(x => x.GetCopy())
    .Where(x => x.IsValid).ToList();

d = d.ConvertAll(x => x.GetCopy())
    .Where(x => x.IsValid).ToList();

C#
// after
a = a.GetChanged();
b = b.GetChanged();
c = c.GetChanged();
d = d.GetChanged();

The problem is I have to choose between DRY principle sacrifice and empty interface, which means the code smell (CA1040: Avoid empty interfaces (code analysis) - .NET | Microsoft Learn[^]).
Is there an elegant way to avoid both?

What I have tried:

I created base abstract class CommonObj that implements both ICopy and IValid interfaces. But IObj cannot be inherited from class, and class ObjD is already inherited from ObjX, which is not supposed to be inherited from CommonObj class.

Also I found this article (Combining Interfaces : C Sharp[^])
Posted
Updated 6-Oct-22 2:18am

1 solution

Just add both interfaces as constraints:
C#
public static List<T> GetChanged<T>(this List<T> src) where T : ICopy<T>, IValid
{
    return src
        .ConvertAll(x => x.GetCopy())
        .Where(x => x.IsValid).ToList();
}
 
Share this answer
 
Comments
RuthWa 6-Oct-22 20:10pm    
Thanks a lot. I didn't know that unlike multiple classes I really can use multiple interfaces as constraint.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900