Reputation: 459
I have written some code and I'm curious as to whether or not there is a danger in what I'm doing that I'm unaware of.
I have tried searching and most of the questions I found dealt with how to make things generic which isn't my issue. I also looked in the C# spec for .net 4.5 under section 13.4.3 - Generic Methods and 7.5.2 in regards to Type inference and finally 7.5.2.12 Inferred return type and they don't really cover what I'm trying to do.
Basically I have a hierarchy of classes
public class SomeBaseClass { }
public class SomeClass : SomeBaseClass { }
public class AnotherClass : SomeBaseClass { }
public class BaseData
{
public SomeBaseClass mMember;
public BaseData() { }
public TType GetMember<TType>()
where TType : SomeBaseClass
{
return (TType)mMember;
}
}
public class Data : BaseData
{
public Data()
{
mMember = new SomeClass();
}
//Is this bad
public SomeClass GetMember()
{
return base.GetMember<SomeClass>();
}
}
The compiler doesn't complain because I'm not hiding the base class method. This is shown that intellisense lists them as two separate methods. I've written several tests which all behave the way I would expect them to and when looking at things like List<> there are instances of methods that have both a generic and nongeneric implementation (for example AsParallel from ParallelEnumerable) but the difference is that in this case both methods exist in the same class and take in a generic and nongeneric parameter respectively.
The tests I ran and showed work the way I would expect are listed below.
class Program
{
static void Main(string[] args)
{
BaseData lData = new Data();
Data lData2 = new Data();
//Call base method with type
SomeBaseClass lTest = lData.GetMember<SomeClass>();
//Cast and call derived method
SomeClass lTest2 = ((Data)lData).GetMember();
//Call base method with type and then cast
SomeClass lTest3 = (SomeClass)lData.GetMember<SomeBaseClass>();
//Call derived method directly
SomeClass lTest4 = lData2.GetMember();
//Throw InvalidCastException
SomeBaseClass lTest5 = lData2.GetMember<AnotherClass>();
}
}
The main reason for this is that I would like that any caller code doesn't have to know the generic type when the class itself already has this information. It's to avoid having to write
lData.GetMemberType<...>();
all over the place.
I apologize if this question is too broad or opinionated. Mostly I'm just wondering if there is anything in this scenario that wouldn't work the way I would think or have a hidden bug etc.
Upvotes: 3
Views: 591
Reputation: 101768
Your question is a little too vague to give a very good answer (what are you using this for? what is the purpose of this design?).
I don't think the name overlap is all that problematic, but it does seem like a symptom of a problematic design and a misuse of generics (all that casting should clue you in on that).
Ideally, your class itself should be generic, and you should use the generic type parameter throughout. That will save you from all the casting you are doing:
public class SomeBaseClass { }
public class SomeClass : SomeBaseClass { }
public class AnotherClass : SomeBaseClass { }
public class BaseData<TType> where TType : SomeBaseClass
{
protected TType mMember;
public BaseData() { }
public BaseData(TType member)
: this()
{
mMember = member;
}
public TType GetMember()
{
return mMember;
}
}
public class Data : BaseData<SomeClass>
{
public Data()
: base(new SomeClass())
{
}
// no need to implement GetMember(); base class has it covered
}
Upvotes: 1