I have a couple of questions about my understanding of an area of .NET.
Please consider the following mockup:
interface IListInterface<T>
{
//brevity
}
interface IClassInterface
{
int Count { get; }
}
class A<T> : IClassInterface
{
List<IListInterface<T>> MyList = new List<IListInterface<T>>();
public virtual int Count { get { return MyList.Count; } }
public void Add(IListInterface<T> item) { MyList.Add(item); }
public IEnumerable<String> GetAllAsString(T source) { return MyList.Select(o=>o.ToString()); }
}
class B<T1, T2> : A<T1>
{
List<IListInterface<T2>> MyList = new List<IListInterface<T2>>();
public override int Count { get { return base.Count + MyList.Count; } }
public void Add(IListInterface<T2> item) { MyList.Add(item); }
public IEnumerable<String> GetAllAsString(T1 source1, T2 source2)
{
return base.GetAllAsString(source1).Union(MyList.Select(o => o.ToString()));
}
}
class C<T1, T2, T3> : B<T1, T2>
{
List<IListInterface<T3>> MyList = new List<IListInterface<T3>>();
public override int Count { get { return base.Count + MyList.Count; } }
public void Add(IListInterface<T3> item) { MyList.Add(item); }
public IEnumerable<String> GetAllAsString(T1 source1, T2 source2, T3 source3)
{
return base.GetAllAsString(source1, source2).Union(MyList.Select(o => o.ToString()));
}
}
My questions are:
What is the term used to describe what Class B and Class C are doing? Generic type overload inheritance?
There tends to be a lot of repeated code when doing writing such an object, especially wh开发者_如何转开发en adding more methods which end up just calling its base, and adding its own information to the return. Is there a better way to go about this to allow for a more maintainable class file?
Edited to address the necessity of this method
By using this type of inheritance, one could define a single object which would constrain the requirements for data input and explain its usage.
var x = new C<String, int, DateTime>();
You now know the types which make up the object and you will get a compile-time error if you attempt to call x.GetAllAsString(0, "hello", "world");
This type of object may not work for you, and its fitness for use is not the subject of my question. My questions are about the name of this method and about code reuse in this situation.
[For brevity; for the purposes of my answer, I'm going to focus only on the 'Add' method, as the question/solution applies to your entire model]
Unfortunately, I don't believe you can simplify what you have already implemented. In effect, what you are aiming to do is to constrain a type ('C') at runtime to a set of available types, which (if it worked!) would give you a limited subset of Add/GetAllAsString methods.
So, after going through the compiler, it sounds like you're hoping to turn a single class with a single method like;
public class Base<T>
{
Add(IListInterface<T> o);
}
into a runtime object that exposes an interface like;
public class C
{
Add(IListInterface<string> o) { ... }
Add(IListInterface<DateTime> o) { ... }
Add(IListInterface<int> o) { ... }
}
But, you can't really use generics in that way. The only way to really accomplish this is to approach it the way you have; with a stack of derived types which each add another constrained method to your type.
精彩评论