I have two intefaces:
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)
public interface IObj: ICopy<IObj>, IValid {}
public class ObjA : ICopy<ObjA>, IValid {}
public class ObjB : ICopy<ObjB>, IValid {}
public class ObjC : IObj {}
public class ObjD : ObjX, IObj {}
public abstract class ObjX {}
And I need some thing like
public interface ICommon<T> : ICopy<T>, IValid { }
so I could create some list extention where list item is of type that implements both
ICopy
and
IValid
interfaces
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.
public interface IObj: ICommon<IObj> {}
public class ObjA : ICommon<ObjA> {}
public class ObjB : ICommon<ObjB> {}
public class ObjC : IObj {}
public class ObjD : ObjX, IObj {}
public abstract class ObjX {}
List<ObjA> a = new();
List<ObjB> b = new();
List<ObjC> c = new();
List<ObjD> d = new();
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();
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[
^])