I ended up with something like the following code in a project I'm working on. I thought it was really odd that I was allowed to do it, but now I'm starting wonder what is most likely an architectural gaff on my part led me to this.
My questions to you are:
What exactly is this called?
What are some real world uses of this?
Why would anyone want to do this?
Here are my Interfaces:
namespace ThisAndThat
{
public interface ICanDoThis
{
string Do();
}
public interface ICanDoThat
{
string Do();
}
public interface ICanDoThisAndThat : ICanDoThis, ICanDoThat
{
new string Do();
}
}
Here's my concrete class:
namespace ThisAndThat
{
public class CanDoThisAndThat : ICanDoThisAndThat
{
public string Do()
{
return "I Can Do This And That!";
}
string ICanDoThis.Do()
{
return "I Can Do This!";
}
string ICanDoThat.Do()
{
return "I Can Do That!";
}
}
}
And my passing tests:
using Xunit;
namespace ThisAndThat.Tests
{
public class ThisAndThatTests
{
[Fact]
public void I_Can_Do_This_And_That()
{
ICanDoThisAndThat sut = new CanDoThisAndThat();
Assert.Equal("I Can Do This And That!", sut.Do());
}
[Fact]
public void I_Can_Do_This()
{
ICanDoThis sut = new CanDoThisAndThat();
Assert.Equal("I Can Do This!", sut.Do());
}
[Fact]
public void I_Can_Do_That()
{
ICanDoThat sut = new CanDoThisAndThat();
Assert.Equal("I Can Do That!", sut.Do());
}
}
}
There is absolutely nothing wrong with this code (provided it isn't confusing for your users), and it isn't a pattern with any name that I'm familiar with. CanDoThisAndThat implements two interfaces, so clients can use it in either way.
.NET allows interfaces to be implemented this way -- known as explicit interface implementation.
Explicit interface implementation is useful when:
Two interfaces have the same member definition
You need to implement an interface but don't want to publicise that a particular member is available to client code that has not declared a reference using the interface type
An example of case 2 from the .NET framework is ICollection.SyncLock. List<T> implements ICollection yet the following code will not compile because the member has intentionally been 'hidden' as the designers of the BCL no longer advocate locking collections in this way:
List<object> list = new List<object>();
lock (list.SyncRoot) // compiler fails here
{
// ...
}
Any legacy code of this format will still work, because the reference is of type ICollection explicitly:
ICollection list = new List<object>();
lock (list.SyncRoot) // no problem
{
// ...
}
Each type has an interface mapping (which can be retrieved with Type.GetInterfaceMap if you want to look at it with reflection). This basically says, "When method X on interface Y is invoked, this method Z is the one to call." Note that even though it's not supported in C#, it's possible for the mapping target method to have a different name from the interface method name! (VB explicitly supports this, I believe.)
In your case, you have three methods and each of the three methods corresponds to a method in one of the interfaces involved.
When the compiler issues a call to a virtual method via an interface, the IL generated says something like "call IFoo.Bar on this object" - and IFoo.Bar is then resolved using the interface map.
You may sometimes need to use it if either you have signatures which differ only in return type, or if you're implementing two heterogeneous interfaces which happen to have the same method names but should do different things. Wherever you can avoid it though, do! It makes for very confusing code.
Related
I have an interface which I am mocking with 'NSubstitute' which contains properties that return concreate classes, that is the return value is not an interface. e.g
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
The 'SomeObj' concrete class has a default constructor but 'NSubstitute' always returns 'null' for these properties. The class itself is not under my control so I cannot simply make it derive from an interface.
Can 'NSubstitute' mock these type of properties? Or is there a way to override the behaviour? Otherwise I have to manually initialise the mock before the test and that can be a lot of code (even if its reused through a common method).
Perhaps there is a simpler solution that I have over-looked?
Classes will be auto-mocked if they have a default (parameterless) constructor and all its members are virtual (see the note in the intro of Auto and recursive mocks). The aim of this is to reduce the potential for unwanted (destructive?) side-effects if we are using a substitute and suddenly hit a non-virtual, unmocked code path that does bad stuff in an instance we thought was fake.
NSubstitute doesn't have a way override this behaviour. Instead, I'd recommend creating all your substitutes via your own factory method (e.g. a static Sub.For<T>(...) method in your test project) that uses NSubstitute to produce a substitute, then applies all the specific initialisation rules you need, like using reflection to stub out values for each class property.
Hope this helps.
Possibly related links:
I advise trying to avoid mocking types we don't own.
Stack Overflow: Is it recommended to mock concrete class?
Hacky factory method sample that subs properties using reflection.
It doesn't count as auto-mocking but you did also ask "Or is there a way to override the behaviour?" and "Perhaps there is a simpler solution that I have over-looked?"
This answer relies on the statements in your question that:
SomeObj is a class outside of your control, from which I assume it is either separately tested or else not testable
SomeObj has a default constructor
Sure, it requires you to "manually initialise the mock before the test" but since you've not told us what this object is it's not possible to know how much work it would take to implement fully.
public class SomeObj
{
// Non-virtual to prevent auto-mocking
public void Dummy() { }
}
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
[TestMethod]
public void Test_17182355ms()
{
ISomething mockedSomething = Substitute.For<ISomething>();
SomeObj firstObj = mockedSomething.First;
Assert.IsNull(firstObj);
mockedSomething.First.Returns(new SomeObj());
mockedSomething.Second.Returns(new SomeObj());
firstObj = mockedSomething.First;
Assert.IsNotNull(firstObj);
}
Another approach, though not without its own drawbacks, would be to extract your own interface for SomeObj, something like this:
public interface ISomeObj
{
void Dummy();
}
public class MySomeObj : SomeObj, ISomeObj
{
}
and then mock ISomeObj in your test.
Is it possible to declare a generic collection to hold only objects implementing a generic Interface with any <T>?
My question burns down to: If I want to/have to store objects implementing a generic interface, is there a better way to express that fact than using a non generic collection or (generic of <Object>).
Example:
// An example Generic Interface
interface ISyncInterface<T>
{
Task DoSync();
IEnumerable<T> NewItems { get; }
}
// a manager-class that registers different classes implementing
// the generic interface.
// The code works - can it be done better?
class Manager
{
private List<Object> _services = new List<Object>(); // <- works but is basically non generic
// however the RegisterService() ensures that only correct types can be added.
// would like to have something like below to indicate the Interface-Type
// however: this would only allow _services2.Add to hold types of ISyncInterface<Object>
// - ISyncInterface<ServiceA_DTO> would fail.
private List<ISyncInterface<Object>> _services2 = new List<ISyncInterface<Object>>();
void RegisterService<T, U>(T service)
where T : ISyncInterface<U>
{
_services.Add(service); // <- works e.g. for SyncServiceA
// _services2.Add(service); // <- FAILS for SyncServiceA - no conversion
// _services2.Add((ISyncInterface<Object>) service); // <- FAILS also - no explicit cast
}
}
// SETUP - The classes used above. Just to clarify.
class ServiceA_DTO { }
class ServiceB_DTO { }
class SyncServiceA : ISyncInterface<ServiceA_DTO>
{
public Task DoSync() {}
public IEnumerable<ServiceA_DTO> NewItems { get; }
}
class SyncServiceB : ISyncInterface<ServiceB_DTO>
{
public Task DoSync() {}
public IEnumerable<ServiceB_DTO> NewItems { get; }
}
Is this possible at all? Any advice is highly appreciated!
Update: New, more verbose code to clarify the problem.
Below there was a suggestion to base the generic interface on an non generic one. But as a consequence all implementing classes of the generic interface would have to implement the non generic methods, properties etc. - or is there a way around it?
Thanks for your input!
Is it possible to declare a generic collection to hold only objects implementing a generic interface instantiated with any T?
Short answer: no.
Longer answer: no, because that is not useful.
Let's consider a simple generic interface:
interface I<T> { T Get(); }
And a bunch of objects that implement it:
class Lion : I<Lion>
{
public Lion Get() => this;
}
class TaxPolicyFactory : I<TaxPolicy>
{
public TaxPolicy Get() => new TaxPolicy();
}
class Door: I<Doorknob>
{
public Doorknob Get() => this.doorknob;
...
}
OK, now suppose you have a List<I<ANYTHING>> like you want:
var list = new List<I<???>> { new TaxPolicyFactory(), new Lion(), new Door() };
You've got a list with a tax policy factory, a lion and a door in it. Those types have nothing in common with each other; there's no operation you can perform on each of those objects. Even if you could call Get on each of them, then you'd have a sequence with a tax policy, a lion and a doorknob in it, and what are you going to do with that?
Nothing, that's what. The constraint "implements interface I<T> for any T" is simply not a useful constraint in C#, so there is no way to express it.
It sounds like you have an "XY" problem. That is a problem where you have a bad solution in mind, and now you are asking questions about your bad solution. Ask us a question about the real problem you have, not the bad idea you've got for its solution. What's the real problem?
UPDATE: With the new information in the question it is now much more clear. The feature you want is called generic interface covariance, which was my favourite feature for C# 4.
If you update your interface definition to
interface ISyncInterface<out T> { ... }
then you can use an ISyncInterface<String> in a context where an ISyncInterface<Object> is expected. For example, you could put an ISyncInterface<Giraffe> into a List<ISyncInterface<Animal>> or whatever.
However you are required to ensure that your interface definition only uses T in a covariantly valid position. Your interface is valid as stated, but if for example you ever want to add a method void M(T t); to your interface, it will no longer be covariantly valid. The "out" is a mnemonic telling you that T can only be used as output of methods. Since IEnumerable<T> is also covariantly valid, it's fine; there are no inputs of T in an IEnumerable<T>.
Also, variance only works with generic interfaces and delegates, and the varying types must be reference types. You can't put an ISyncInterface<int> into a List<ISyncInterface<Object>> because int is not a reference type.
There are many posts on SO about covariance and contravariance; you should also read the Microsoft documentation. It can be a confusing feature. If you're interested in the historical details of how we designed and implemented the feature, see my blog.
Perhaps you can try something like this:
public interface MyInterface
{//methods common to all types
void FirstMethod();
}
public interface MyInterface<T> : MyInterface
{//methods specific to a type
void FirstMethod(T parameter);
}
public class MyClassThatHandlesAllInterfaces
{
private List<MyInterface> _allInterfacesT; //first interface in the chain
public void AddInterface<T>(MyInterface<T> ifToAdd)
{
_allInterfacesT.Add(ifToAdd); // <- this is what I'd like to do
}
}
I use this pattern quite often. Because I do not know all the details about your scenario it might not be suitable for you.
But it might help other people searching google.
I'm starting to see this pattern appear often in my code:
class Foo { }
interface IBar
{
Foo Foo { get; }
}
class Bar<TFoo> : IBar where TFoo : Foo
{
public TFoo Foo { get; private set; }
Foo IBar.Foo
{
get
{
return Foo;
}
}
}
Some of its benefits are:
An easy way to check whether an object is of the wrapping type (if (something is IBar))
Strong-typed access to TFoo in closed-constructed Bar<>s
Polymorphic access to Foo in interfaced IBars
One could argue that this kind of pattern is everywhere in the framework (e.g. List<T> : IList), but I wonder if this is just a remnant of .NET 1.0, when generics didn't exist.
Off the top of my head, my main concern is that IBar is not necessarily a proper contract that defines what members a "bar" should provide; it's only a hack to access generically typed members.
Also, if I start adding interfaces for that purpose, I quickly end up with hard to maintain parallel inheritance hierarchies.
Should I be worried about spreading this pattern in my code base? If so, what alternative patterns would provide some or all of the 3 benefits listed above?
Because explicitly implementing abstract members is not allowed, this "ideal" solution is not possible:
class Foo { }
class Bar
{
public abstract Foo Foo { get; }
}
class Bar<TFoo> : Bar where TFoo : Foo
{
private TFoo foo;
Foo Bar.Foo
{
get
{
return foo;
}
}
public new TFoo Foo
{
get
{
return foo;
}
}
}
For me, the summary is you shouldn't think that you implement interfaces just for the sake of augmenting a generic type parameter with more typing.
AFAIK, you use interfaces to provide which are the contracts to work with a given API. Generics are just a language feature/tool to provide more typing where you would end up doing a lot of casts. Hereby, with generics you limit your API to expect arguments implementing one or more interfaces and also with some requirements using generic constraints.
For example, if you just want to accept implementations of given interface called IWhatever, would you use generics?
public void DoStuff<T>(T whatever)
where T : IWhatever
{
}
// versus
public void DoStuff(IWhatever whatever)
{
}
BTW, without generics, how you would check that an implementation to IWhatever is a class and has a public constructor? You would end up with reflection and you're code would smell compared to using generics:
public void DoStuff<T>()
where T : class, IWhatever, new()
{
}
In fact, a generic parameter can constraint that T must inherit a given class and implement one or more interfaces:
public void DoStuff<T>(T arg)
where T : A, IEquatable<T>, IWhatever, IWhichever, IWherever
{
}
And whether if T inherits a type with or without generic parameters or implements interfaces with or without generic parameters, it's not a good or bad design per se but, again, just a language tool that's suitable to specific cases.
Therefore, your statement...
Off the top of my head, my main concern is that IBar is not
necessarily a proper contract that defines what members a "bar" should
provide; it's only a hack to access generically typed members.
...describes a particular design flaw instead of an actual problem with typing generics using the wonders of interfaces.
Conclusion: if IBar isn't a proper contract, then you should revisit your architecture and re-think your solution.
More background on the topic
Actually I thought that my original answer implied that I found the whole solution has a design flaw.
In summary, you're using interfaces to expose an association on certain classes which provide the type of the whole association using a generic type parameter. And you argue that you do this to be able to access such association in a less typed context:
However, I sometime need a "less" typesafe context, hence my question.
And then it's when covariance enters in action! See the following code sample:
public class SuperClass
{
}
public interface IWhatever<out TAssociation>
where TAssociation : SuperClass
{
TAssociation Association { get; }
}
public class SomeImplementation<TAssociation> : IWhatever<TAssociation>
where TAssociation : SuperClass
{
public TAssociation Association { get; set; }
}
Now let's define a derived class of SuperClass:
public class DerivedClass : SuperClass
{
}
And see how this works like a charm:
SomeImplementation<DerivedClass> someImpl = new SomeImplementation<DerivedClass>();
// Covariance: you decide the degree of specialization of TAssociation
// interfaces' type parameter. In our case, we'll upcast TAssociation to
// the SuperClass type.
IWhatever<SuperClass> whatever = someImpl;
Clearly this is the way to go since C# 4.0.
I would say that the right way of expressing your requirement is you need a less specialized context instead of a less typed context. Covariance/contravariance is one of the most powerful features available in C# to cover this scenario when generics are involved in the equation.
This practice isn't a code smell per se. In my case, I go for it when I really need to access one or more associations somewhere where I just need to access certain members with a concrete purpose.
For example, if I'm building a tree-style hierarchy, I would define an interface like this:
public interface IHasParent<out TParent>
{
TParent Parent { get; }
}
Which enables me to do this:
IHasParent<object> withParent = someObject as IHasParent<object>;
if(withParent != null)
{
// Do stuff here if some given object has a parent object
}
But I don't create interfaces indiscriminately because some day I'll need less typed access to some properties. There should be a well defined purpose. Otherwise, you can end up turning a nice solution into a code smell.
You would say don't repeat yourself but I still feel that there's no definitive answer without analyzing your project code base and checking how you really use this kind of interfaces to solve concrete problems.
So, strictly talking, if you use the whole pattern when it's really required, it should be a good design decision.
Maybe you want to avoid the unavoidable
Based on some chat we've had both the OP and me, I feel that the best conclusion is that the OP wants to avoid the unaviodable.
In an object-oriented language like C# interfaces are the right tool to both define type contracts and expose a subset of a full type implementing some interface.
Also, the OP would love a feature in C# like protocols where a class that implicitly fullfils an interface is enough to consider that it implements the interface which would save up many code lines if C# could have this feature:
public interface IWhatever
{
void DoStuff();
}
public class X
{
void DoStuff();
}
public class Y
{
public void HandleStuff(IWhatever whateverImpls)
{
}
}
Y y = new Y();
// Protocols would support passing an instance of X which may not implement
// IWhatever but it implicitly fulfills IWhatever:
y.HandleStuff(new X());
BTW, C# lacks this feature. Therefore, it's a waste of time scratching your head thinking how sweet would be having such feature. You need to deal with what C# has to offer already.
Anyway, if you just need to expose some associations across your object graph and get them selectively, you can use the wonders of interfaces using a more simplified approach than yours. Did you know that you can explicitly implement the same interface more than once if its generic arguments vary?
Why don't you design an interface like this:
public interface IHasAssociation<out TAssociation>
{
TAssociation Association
{
get;
}
}
public interface IHasManyAssociation<out TEnumerable, out TAssociation>
where TEnumerable : IEnumerable<TAssociation>
where TAssociation : Entity
{
TEnumerable Association
{
get;
}
}
public class Entity
{
}
public class Company : Entity
{
}
public class CustomerProfile : Entity
{
}
public class Contact : Entity
{
}
public class Customer :
IHasAssociation<Company>,
IHasAssociation<CustomerProfile>,
IHasManyAssociation<IList<Contact>, Contact>
{
public Company Company
{
get;
set;
}
public CustomerProfile Profile
{
get;
set;
}
public IList<Contact> Contacts
{
get;
set;
}
Company IHasAssociation<Company>.Association => Company;
CustomerProfile IHasAssociation<CustomerProfile>.Association => Profile;
IList<Contact> IHasManyAssociation<IList<Contact>, Contact>.Association => Contacts;
}
Definitively this keep things simpler (KISS!) because you don't need a parallel interface object graph definition, you simply define an interface to being able to get an association of a given type:
var customer = new Customer();
customer.Profile = new CustomerProfile();
customer.Company = new Company();
customer.Contacts = new List<Contact>();
var withCompany = customer as IHasAssociation<Company>;
var withCustomerProfile = customer as IHasAssociation<CustomerProfile>;
var withContacts = customer as IHasManyAssociation<IList<Contact>, Contact>;
if (withCompany != null)
{
Company company = withCompany.Association;
Console.WriteLine("This object has an associated company!");
}
if (withCustomerProfile != null)
{
CustomerProfile profile = withCustomerProfile.Association;
Console.WriteLine("This object has a profile!");
}
if (withContacts != null)
{
IList<Contact> contacts = withContacts.Association;
Console.WriteLine("This object has contacts!");
}
Also, see covariance in action:
if(customer is IHasManyAssociation<IEnumerable<Contact>, Contact>)
{
Console.WriteLine("This object has an enumerable of contacts!");
}
Or here's how you would get all association values of an implementor of one or many IHasAssociation<out TAssociation> interface implementations:
var entityAssociations = typeof(Customer)
.GetInterfaces()
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHasAssociation<>))
.Select(i => i.GetProperty("Association").GetValue(customer));
foreach(var entityAssociation in entityAssociations)
{
Console.WriteLine($"{entityAssociation.GetType().FullName}");
}
This is the real beauty of generic programming! And remember: you won't need to implement IHasAssociation<out TAssociation>/IHasManyAssociation<out TEnumerable, out TAssociation> indiscriminately. That is, you implement on the classes to which associations need to be extracted in some place where you don't care who's the concrete owner of the association and you just need the association itself.
In your question, you express the need for a "generic" wrapper type (note I use the term "generic" here independently of any language).
Well, I don't see any problem with that. And if you ask me how to do it with .NET, I would just design this, once for all types, going one step further from you:
interface IWrapper<T>
{
T BaseObject { get; }
}
Then, a wrapper class would simply be:
class Bar<TFoo> : IWrapper<TFoo> where TFoo : Foo
{
public TFoo BaseObject { get; private set; }
}
I could go further again and define the non generic one, because it's ofen desirable to have both, as it's sometimes hard to work with generic-only clases/interface with meta/reflection code (but this is really optional):
interface IWrapper
{
object BaseObject { get; }
}
If you do this, it could be natural to have IWrapper<T> derive from IWrapper, like this:
interface IWrapper<T> : IWrapper
{
new T BaseObject { get; }
}
And the class would be this:
class Bar<TFoo> : IWrapper<TFoo> where TFoo : Foo
{
public TFoo BaseObject { get; private set; }
object IWrapper.BaseObject => BaseObject;
}
PS: as a side note, you can have a look at WCF's ServiceModel ChannelFactory<T> class that has a combined generic/non generic hierarchy somewhat relevant with your question.
I've found myself in a similar place after developing an API.
I have some questions for you and no answers.
But once you can answer those questions, maybe you know a bit more about how to address this situation.
I wonder how many classes implement IBar.
Are there enough to justify it?
Is this an API and you expose it to client code?
In how many code points do you leverage the polymorphism of the interface?
Just maybe... those answers can make you question the interface's usefulness.
How many times does this structure emerge?
And are you sure it actually does?
I mean, you say you did this:
implement lots of code (A);
refactor it in one place to clean it up;
implement more code (B);
refactor it to clean it up;
notice that B looks similar to A;
implement more code (C);
refactor it to clean it up;
notice that C looks similar to B (by transitivity also to A);
repeat...
Did the structure REALLY emerge, or is it your thinking that mold the code always in the same way?
Which comes first?
the emergence;
the thinking.
This "rinse" and "repeat" approach may be good to start, but just maybe... you've grown out of this methodology and should approach another one:
First design, then implement.
Is this your case? Have you grown that much, that you can finally approach design before implementation?
There's a saying that may apply here:
When you have a hammer, everything looks like a nail.
But let's assume this is not your case.
You don't fall into thought cycles and the underlying problem REALLY has this structure, thus your code reflects the problem's structure.
If you really came up with the same thing multiple times, but it's the problem, not your mind playing tricks, then the following may be a good advice.
Stop coding for a day, and think about it away from keyboard.
Which parts are the same, which different?
Can't you implement this in an even MORE abstract way (actual pattern) into which you inject the specialized code?
Maybe, underlying it all, is a something as simple as a composite pattern, and you could just implement that once and for all, and then reuse it all over the place.
What happened to me was similar, and I ended up with a dependency injection, an abstract factory, an abstract implementation of the composite pattern and an information expert, which took a configuration file and assembled the final object graphs I needed.
It was an excellent, humbling lesson in patterns and architecture, but I regretted actually using it.
Writing the documentation was near impossible and futile.
The code became extremely difficult to follow.
I always had to look things up and rethink about how to use it correctly.
The end result was not that astonishing.
So, if you want to learn and exercise, don't ever stop!
But if you want to just get it done and move on, don't overthink it.
Simple is better!
You may be in a place where you try to perfect your code but actually don't need it.
You're not writing a new API for M$, are you?
Just take this advice:
In a year or two, you won't be able to understand your own code. You must document it, if you make it that complex. If you can't document it, you'll never reuse it. So you don't need this perfection, it will be throw-away code.
In other words:
The real value is not the code, but the documentation that accompanies it. Without documentation there will be no reuse..
In retrospect, I've learned that the correct term for what I want is return type covariance, which is unfortunately not supported in C#, because the language design team does not consider the benefits of implementing the feature outweigh the cost, even though it preserves type safety. (A proposal has been drafted and completed, but it seems to be abandoned).
With return type covariance, the example code could be written as:
class Foo { }
class Bar
{
public virtual Foo Foo { get; }
}
class Bar<TFoo> : Bar where TFoo : Foo
{
public override TFoo Foo { get; }
}
The workaround proposed by Eric Lippert in that linked question is:
class Foo { }
abstract class Bar
{
protected abstract Foo foo { get; }
public Foo Foo => foo;
}
class Bar<TFoo> : Bar where TFoo : Foo
{
protected override Foo foo => this.Foo;
public new TFoo Foo { get { ... } }
}
It has the downside of duplicating not the inheritance hierarchy, but every covariant-simulated property per level of inheritance!
For further reading on how much clutter simulating covariant return types can bring to your code, consider that implementing ICloneable properly implies adding another virtual method per level of inheritance. I'll leave this as my humble plea for that language feature.
Context: .NET 4.0, C#
I'm creating a set of interfaces and a set of clases that implement them to provide some service. The clients use the concrete clases but call methods that are declared using the interfaces as parameter types.
A simplified example is this one:
namespace TestGenerics
{
// Interface, of fields
interface IField
{
}
// Interface: Forms (contains fields)
interface IForm<T> where T : IField
{
}
// CONCRETE CLASES
class Field : IField
{
}
class Form <T> : IForm<T> where T : IField
{
}
// TEST PROGRAM
class Program
{
// THIS IS THE SIGNATURE OF THE METHOD I WANT TO CALL
// parameters are causing the error.
public static void TestMethod(IForm<IField> form)
{
int i = 1;
i = i * 5;
}
static void Main(string[] args)
{
Form<Field> b = new Form<Field>();
Program.TestMethod(b);
}
}
}
The code makes sense to me, but I get the compiler error:
Argument 1:
cannot convert from 'TestGenerics.Form<TestGenerics.Field>' to
'TestGenerics.IForm<TestGenerics.IField>' TestGenerics
I'm not sure what I'm doing wrong, I've read lots of pages on the internet but none solved my problem.
Is there a solution that would not modify that much the architecture of what I'm trying to build:
Edit:I designed the interfaces in a way such that they should be independent of concrete clases that implement them. The concrete clases could be loaded from a dll, but most of the application Works with the interfaces. In some cases I need to use concrete clases, specially when using clases that need to be serialized.
Thanks in advance.
Alejandro
The problem is that Form<Field> implements IForm<Field> but not IForm<IField>. You cannot use an inherited class (or interface) as a generic parameter unless it is marked as covariant with the out identifier. However, marking your interface as covariant will restrict the usage significantly (basically making in an "output-only" interface like IEnumerable) so it may not work for you.
One way to get it to work is to make TestMethod generic as well:
public static void TestMethod<T>(IForm<T> form) where T:IField
{
int i = 1;
i = i * 5;
}
You can use Covariance, like so:
interface IForm<out T> where T : IField
{
}
More about Covariance and Contravariance here.
Others have pointed out the reasoning behind the error message, but let's examine the design of your sample code for a moment. Perhaps you're using a generic where none is needed.
You've already said you're using methods declared in the IField interface, so there may be no need to make your IForm class generic - simply have it store references to IField, instead of the generic argument 'T' (which is already guaranteed to be an IField anyway).
For instance, use:
public interface IForm
{
IEnumerable<IField> Fields { get; set; }
}
instead of
public interface IForm<T> where T : IField
{
IEnumerable<T> Fields { get; set; }
}
I'd appreciate any advice on which way to go on in the following scenario. Let's see if I can explain it clearly (english is not my native language so things might get confusing, sorry).
Suppose I have the following interfaces:
internal interface IBlah
{
int Frob();
}
internal interface IBlahOnSteroids: IBlah
{
double Duh();
}
Now we have a Foo class with a 'has a' relationship with an IBlah object:
public class Foo
{
IBlah blah;
internal Foo(IBlah blah)
{
this.blah = blah;
}
public int Frob()
{
....
return this.blah.Frob();
}
}
Now we also need a FooOnSteroids class that has a 'has a' relationship with a IBlahOnSteroids object.
The question is, knowing that part of IBlahOnSteroids is already implemented in Foo, what happens if we create
FooOnSteroids inheriting from Foo?
We would get something like this:
public class FooOnSteroids: Foo
{
IBlahOnSteroids blah;
internal FooOnSteroids(IBlahOnSteroids blah)
:base(blah)
{
this.blah = blah;
}
public double Duh()
{
return this.blah.Duh();
}
}
Is this a recommended pattern? We are passing down the inheritance chain the same 'blah' object and at each "level" we are storing it in a private
field with a 'useful' type. There is no way, that I can see, that I could store in BlahBase a protected property that
exposed one common IBlah reference to all descending classes as it would have to be of type IBlah wich would be of no use to BlahOnSteroids. Is this scenario even
recommended? Or should we just implement Foo and FooOnSteroids as independent classes with no inheritance (this would create code duplication)? Maybe its absolutely fine to do this, but it somehow feels like a hack. Is it?
The option of using generics, which would solve the problem in no time, is not possible as, yes I know it sucks, this library must target .Net 1.x platforms.
The option of just implementing BlahOnSteroids is also a possibility but it would mean that depending on the caller, we would have to throw an exception if any of
IBlahOnSteroids members was called. I dont like that.
Thanks a lot for any advice!
You could reduce the duplication by making the base field available:
IBlah blah;
protected IBlah Blah { get { return blah; } }
and cast at the sub-type (since you expect your choice of blah to be respected):
public double Duh() {
return ((IBlahOnSteroids)Blah).Duh();
}
You could also do something with generics on the base-type (to avoid the cast) but I'm not sure it is worth it. Note, however, that this might explode if the base-class decides to inject a decorator abound blah (if the decorator doesn't provide the second interface).
One alternative pattern is
public class Foo
{
protected IBlah Blah { get; private set; }
...
}
public class FooOnSteroids : Foo
{
private new IBlahOnSteroids Blah { get { return (IBlahOnSteroids)base.Blah; } }
...
}
However, this isn't very different from your code; if you can't use generics, they're both fine.
In response to your question about removing the inheritance between Foo and FooOnSteroids, I don't know all your reasoning, but I can try to provide some general guidance. You should consider using inheritance mainly to provide your clients the ability to use FooOnSteroids instances, but only write the code for Foo.
So, if conceptually your clients do this:
Foo foo = new FooOnSteroids();
foo.Frob()
you should keep the inheritance.
If you are creating the inheritance relationship ONLY to re-use code, I suggest you consider refactoring the classes to contain a class which provides the shared functionality. Inheritance is not the best pattern for code re-use.
Given that you can't use generics (which may or may not make your specific use case easier) I would personally opt for casting the blah member of Foo. Casting in C# is relatively painless:
public double Duh()
{
return (this.blah as IBlahOnSteroids).Duh();
}
The as keyword in C# will evaluate to null if the object can't be cast into the type you requested. In the above example, if this.blah isn't an instance of IBlahOnSteroids you will get a NullReferenceException. You can check if an object is an instance of a type like so:
public double Duh()
{
if (this.blah is IBlahOnSteroids)
return (this.blah as IBlahOnSteroids).Duh();
else
throw new InvalidTypeException("Blah is not an instance of IBlahOnSteroids");
}
Though in the code in your original example it shouldn't be possible for blah to not be an instance of IBlahOnSteroids since it's assigned in the constructor, which makes that assertion at compile time for you.