Reputation: 3494
I need to have a list where all items extend class A and implement interface I. Additionally class A might be multiple parents up in the hierarchy.
If all the classes were direct descendants of class A I could just use an Abstract class that implements I as the generic and use that, but my use case doesn't allow for this.
is there a way to tell a List that its elements must both extend class A and implement interface I ? List<A,I>
? If not is there another way around this?
Example Code:
public class A
{
// Class belongs to a third party library
}
public class B : A
{
// Class belongs to a third party library
public string Text{ get; set; }
}
public class C : A
{
// Class belongs to a third party library
public string Other{ get; set; }
}
interface I
{
// Belongs to me
bool shouldSend();
string getName();
string getValue();
}
public class MyClass : B, I
{
public string Name{ get; set; }
public function myClass(ObjectWithName obj)
{
Name = obj.Name;
}
public string getValue()
{
return Text;
}
public bool shouldSend()
{
return true;
}
}
public class MyClass2 : C, I
{
public string Name{ get; set; }
public function myClass(ObjectWithName obj)
{
Name = obj.Name;
}
public string getValue()
{
return Other;
}
public bool shouldSend()
{
return true;
}
}
public class mainActions
{
// Here is where I need the list to use both restrictions
public List<A,I> myList;
// The class I need to use these things in
public function mainActions(List<ObjectWithName> elements)
{
ThirdPartyCollection TPC = new ThirdPartyCollection();
foreach(var el in elements)
{
MyList.Add(new MyClass(el));
MyList.Add(new MyClass2(el));
// TPC.Add accepts implementations of A here
TPC.Add(MyList.ElementAt(MyList.Count - 1));
TPC.Add(MyList.ElementAt(MyList.Count - 2));
}
}
public function doThisLater()
{
foreach(var el in myList)
{
if(el.shouldSend())
{
// I need an implementation of I here
doSomethingElse(el.getName(), el.getValue());
}
}
}
}
EDIT: For anyone coming in search of an answer here in the future, it doesn't seem to be possible. Instead I used @servys answer and made a new list to hold my sub class objects:
public class MyList<T> : List<T> where T : A, I
{
}
Then I kept different lists for each subclass:
protected MyList<MyClass> MCList = new MyList<MyClass>();
protected MyList<MyClass2> MCList2 = new MyList<MyClass2>();
Upvotes: 0
Views: 77
Reputation: 203850
When you specify generic constraints you can specify as many as you want, and all of them must be met, so you can simply add a generic constraint of A
and I
to your type, and a type has to meet both of those constraints to be a valid generic argument.
public class ClassThatNeedsABetterName<T> : List<T>
where T : A, I
{ }
Upvotes: 4