Method that accepts either one of two interfaces - c#

The problem
I have two interfaces IImporter and IExporter and a class that handles instances of those interfaces:
class IoManager
{
public ReadOnlyCollection<IImporter> Importers { get; }
public ReadOnlyCollection<IExporter> Exporters { get; }
// ...
}
In this class I want to implement a method Add(...) that can add either an importer or an exporter.
I know I could create an overload for both interfaces like
public void Add(IExporter exporter);
public void Add(IImporter importer);
The problem is if I want to add an object that implements both interfaces like CsvIo : IImporter, IExporter via the Add(...) function, I get an ambigious call compiler error because CsvIo is accepted by both overloads.
What I don't want to do
I don't want to rename the overloads to different names, because most types implement both interfaces and I want a coherent behavior for types that implement IExporter, IImporter or both.
I don't want to create a "parent" interface that is implemented by both interfaces, because this seems like a hacky solution
I don't want to cast types in the Add(...) call, like Add((IImporter) CsvIoInstance), because that suggests that only the importer of this type is used. But both overloads check if the object implements both interfaces and adds it to both lists accordingly.
The question
Is there a way of accepting the different types in a coherent manner (so that the call looks the same for each type)?
Edit
To clarify my implementation: this is part of a plugin system. I want to add multiple ways of storing my data (so that it can be used by other applications). The IExporter interface is used for storing the data while the IImporter interface loads the data. The IoManager manages all registered plugins. And of course it is possible (and probably common) that a class implements both, exporting and importing of a certain file format. This is why I wanted the Add(...) function to be similar for all cases.
However, thinking about it again (as already stated in the comments) the plugins are only known at runtime which makes ambiguity an obsolete problem I think. So this is only relevant for built in types.

I'd like to focus on one sentence in particular:
I don't want to cast types in the Add(...) call, like Add((IImporter) CsvIoInstance), because that suggests that only the importer of this type is used. But both overloads check if the object implements both interfaces and adds it to both lists accordingly.
Your current design already gives up one of the goals of type safety: to avoid runtime type checking. Ideally, a method that takes an IImporter parameter should only use that parameter as an IImporter. This forms a sort of "contract" between the caller of the method and the implementer: the implementer trusts that the caller will provide what it needs, and the caller trusts that the implementer will only use it in that way. (See also: Principle of least astonishment.)
Imagine that you're a consumer of this class. There is a collection of IImporters and a method with the signature Add(IImporter foo). What would you expect that method to do? I would expect it to add foo to the list of IImporters - I would not expect it to also do something else because my object happened to implement another interface (such as IExporter). Using the type system in this way "betrays" the contract you've established with the caller.
Change your method names to AddImporter and AddExporter, and then have each method only add the parameter to the corresponding list. That solves the problem with overload resolution, and means that the caller is getting exactly what they asked for.

There's an obvious solution to this problem, but you rule it out with this statement:
I don't want to rename the overloads to different names, because most types implement both interfaces and I want a coherent behavior for types that implement IExporter, IImporter or both.
The problem is that you want to do this:
public void Add(IExporter exporter);
public void Add(IImporter importer);
But you don't want to do this:
public void AddExporter(IExporter exporter);
public void AddImporter(IImporter importer);
Why? You can call the first one an "overloaded method", which it technically is, but it's really just two methods with the same name.
Overloading is when you have have a method that does one thing, but you can do it with different sets of parameters. These two methods actually do two different things. One adds an IExporter and one adds an IImporter. So there's nothing 'incoherent' about giving different names to different methods that do different things. It would be much, much worse to add extra interfaces and complication to your classes just to manipulate the compiler.

It's similar to your request for no parent interface, but what you should have is a child interface that combines the two.
public interface IImporterExporter : IImporter, IExporter {
}
Implement it on your class instead of the two separate interfaces:
class ImporterExporter : IImporterExporter {
}
And then write a third overload:
public void Add(IImporterExporter importerExporter) {
// decide what to do if both interfaces are implemented
}
There is a reason why you end up with the ambiguity problem, and that is because either of the overloads could be correct, or maybe even both of them are correct at the same time. You need to resolve the ambiguity by deciding what to do in that case. Since C# does not have type unions, you must declare a separate interface which unifies them.
Note that this is not "hacky", but is actually good design to combine simpler interfaces into more complex ones. This allows for cleaner and more precise code, which is a good thing. But regardless of that, even if you don't like the idea of combining interfaces for some reason, it is still necessary in C# in order to avoid this exact problem.
Without the third interface, all you're left with is looking for something else that both types have in common, and without a parent interface, you're basically just left with object. This would allow for a single method, but you would lose the benefits of the type system.
public void Add(object obj) {
var maybeImporter = obj as IImporter;
var maybeExporter = obj as IExporter;
if (maybeImporter != null && maybeExporter != null) {
// do something if both are implemented
} else if (maybeImporter != null) {
// importer only
} else
// exporter only
}
}

Related

I don't understand why it is wrong to test for possible interfaces in a base class

I have an abstract base class that will be used in hundreds of derived classes, including an additional abstract class.
There are at least 2 properties (let's call them Purpose and Description, both strings) that will be added to many (but not all) of the concrete derived classes, so I created interfaces (IPurposeful and IDescribable) to add them when needed. All is well so far.
I want a single method that I can call on all classes derived from my base class that will validate and update the Description property if it is indeed IDescribable, or just return true if it is not IDescribable. I'd like another similar method to validate/update the Purpose property.
I achieve this with a method in the base class that looks something like this:
protected bool CheckDescription(bool modify = false)
{
if (this is IDescribable ele)
{
var newDesc = GetCorrectDescription();
UpdateDescription(newDesc, ele.Description, modify);
return newDesc.Equals(ele.Description);
}
else
{
return true;
}
}
SonarQube marks the "this is IDescribable" check as a blocker (bad practice) and I am wondering why? The only other way I can think of to replicate this functionality would be to change the base method to this:
protected virtual bool CheckDescription(bool modify = false)
{
return true;
}
and then add this exact same method to potentially hundreds of derived classes:
protected override bool CheckDescription(bool modify = false)
{
var newDesc = GetCorrectDescription();
UpdateDescription(newDesc, Description, modify);
return newDesc.Equals(Description);
}
Now THAT would seem like bad practice.
EDIT: Changed the is/as pattern to remove redundancy
If your class may be IDescribable and may be IPurposeful, then give it sensible default implementations of those interfaces that may be no-ops and allow your descendant classes to override those implementations as required.
No type checks required. Just call the overridable methods and abide by their outcomes.
If your "optional" interfaces don't allow sensible no-op implementations, re-visit their definitions.
Now your base class can rely on the interfaces, rather than testing for them.
You may introduce runtime errors here - but the same can be said about base class methods that require a specific interface to be implemented that aren't compile-time checkable.
I decided to explore extension methods a bit more and found that for my particular needs they will work fine. I wanted to mark the original suggestion to look at extension methods as the correct answer but cannot seem to find a mechanism to do so.
Anyway, extension methods fulfill my requirements to be able to define a default algorithm in one place for most derived classes and override that behavior in specific derived classes only if/when necessary.
The one downside is that I cannot call the "base" implementation from within the "override" method. This may lead to a need to duplicate code in the future but thankfully for now I have not had that problem.

Implement a class from Interface having implemented methods as static (.NET) [duplicate]

Why was C# designed this way?
As I understand it, an interface only describes behaviour, and serves the purpose of describing a contractual obligation for classes implementing the interface that certain behaviour is implemented.
If classes wish to implement that behavour in a shared method, why shouldn't they?
Here is an example of what I have in mind:
// These items will be displayed in a list on the screen.
public interface IListItem {
string ScreenName();
...
}
public class Animal: IListItem {
// All animals will be called "Animal".
public static string ScreenName() {
return "Animal";
}
....
}
public class Person: IListItem {
private string name;
// All persons will be called by their individual names.
public string ScreenName() {
return name;
}
....
}
Assuming you are asking why you can't do this:
public interface IFoo {
void Bar();
}
public class Foo: IFoo {
public static void Bar() {}
}
This doesn't make sense to me, semantically. Methods specified on an interface should be there to specify the contract for interacting with an object. Static methods do not allow you to interact with an object - if you find yourself in the position where your implementation could be made static, you may need to ask yourself if that method really belongs in the interface.
To implement your example, I would give Animal a const property, which would still allow it to be accessed from a static context, and return that value in the implementation.
public class Animal: IListItem {
/* Can be tough to come up with a different, yet meaningful name!
* A different casing convention, like Java has, would help here.
*/
public const string AnimalScreenName = "Animal";
public string ScreenName(){ return AnimalScreenName; }
}
For a more complicated situation, you could always declare another static method and delegate to that. In trying come up with an example, I couldn't think of any reason you would do something non-trivial in both a static and instance context, so I'll spare you a FooBar blob, and take it as an indication that it might not be a good idea.
My (simplified) technical reason is that static methods are not in the vtable, and the call site is chosen at compile time. It's the same reason you can't have override or virtual static members. For more details, you'd need a CS grad or compiler wonk - of which I'm neither.
For the political reason, I'll quote Eric Lippert (who is a compiler wonk, and holds a Bachelor of Mathematics, Computer science and Applied Mathematics from University of Waterloo (source: LinkedIn):
...the core design principle of static methods, the principle that gives them their name...[is]...it can always be determined exactly, at compile time, what method will be called. That is, the method can be resolved solely by static analysis of the code.
Note that Lippert does leave room for a so-called type method:
That is, a method associated with a type (like a static), which does not take a non-nullable “this” argument (unlike an instance or virtual), but one where the method called would depend on the constructed type of T (unlike a static, which must be determinable at compile time).
but is yet to be convinced of its usefulness.
Most answers here seem to miss the whole point. Polymorphism can be used not only between instances, but also between types. This is often needed, when we use generics.
Suppose we have type parameter in generic method and we need to do some operation with it. We dont want to instantinate, because we are unaware of the constructors.
For example:
Repository GetRepository<T>()
{
//need to call T.IsQueryable, but can't!!!
//need to call T.RowCount
//need to call T.DoSomeStaticMath(int param)
}
...
var r = GetRepository<Customer>()
Unfortunately, I can come up only with "ugly" alternatives:
Use reflection
Ugly and beats the idea of interfaces and polymorphism.
Create completely separate factory class
This might greatly increase the complexity of the code. For example, if we are trying to model domain objects, each object would need another repository class.
Instantiate and then call the desired interface method
This can be hard to implement even if we control the source for the classes, used as generic parameters. The reason is that, for example we might need the instances to be only in well-known, "connected to DB" state.
Example:
public class Customer
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
void SomeOtherMethod()
{
//do work...
}
}
in order to use instantination for solving the static interface problem we need to do the following thing:
public class Customer: IDoSomeStaticMath
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
//dummy instance
public Customer() { IsDummy = true; }
int DoSomeStaticMath(int a) { }
void SomeOtherMethod()
{
if(!IsDummy)
{
//do work...
}
}
}
This is obviously ugly and also unnecessary complicates the code for all other methods. Obviously, not an elegant solution either!
I know it's an old question, but it's interesting. The example isn't the best. I think it would be much clearer if you showed a usage case:
string DoSomething<T>() where T:ISomeFunction
{
if (T.someFunction())
...
}
Merely being able to have static methods implement an interface would not achieve what you want; what would be needed would be to have static members as part of an interface. I can certainly imagine many usage cases for that, especially when it comes to being able to create things. Two approaches I could offer which might be helpful:
Create a static generic class whose type parameter will be the type you'd be passing to DoSomething above. Each variation of this class will have one or more static members holding stuff related to that type. This information could supplied either by having each class of interest call a "register information" routine, or by using Reflection to get the information when the class variation's static constructor is run. I believe the latter approach is used by things like Comparer<T>.Default().
For each class T of interest, define a class or struct which implements IGetWhateverClassInfo<T> and satisfies a "new" constraint. The class won't actually contain any fields, but will have a static property which returns a static field with the type information. Pass the type of that class or struct to the generic routine in question, which will be able to create an instance and use it to get information about the other class. If you use a class for this purpose, you should probably define a static generic class as indicated above, to avoid having to construct a new descriptor-object instance each time. If you use a struct, instantiation cost should be nil, but every different struct type would require a different expansion of the DoSomething routine.
None of these approaches is really appealing. On the other hand, I would expect that if the mechanisms existed in CLR to provide this sort of functionality cleanly, .net would allow one to specify parameterized "new" constraints (since knowing if a class has a constructor with a particular signature would seem to be comparable in difficulty to knowing if it has a static method with a particular signature).
Short-sightedness, I'd guess.
When originally designed, interfaces were intended only to be used with instances of class
IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();
It was only with the introduction of interfaces as constraints for generics did adding a static method to an interface have a practical use.
(responding to comment:) I believe changing it now would require a change to the CLR, which would lead to incompatibilities with existing assemblies.
To the extent that interfaces represent "contracts", it seems quiet reasonable for static classes to implement interfaces.
The above arguments all seem to miss this point about contracts.
Interfaces specify behavior of an object.
Static methods do not specify a behavior of an object, but behavior that affects an object in some way.
Because the purpose of an interface is to allow polymorphism, being able to pass an instance of any number of defined classes that have all been defined to implement the defined interface... guaranteeing that within your polymorphic call, the code will be able to find the method you are calling. it makes no sense to allow a static method to implement the interface,
How would you call it??
public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
public static void MyMethod() { //Do Something; }
}
// inside of some other class ...
// How would you call the method on the interface ???
MyClass.MyMethod(); // this calls the method normally
// not through the interface...
// This next fails you can't cast a classname to a different type...
// Only instances can be Cast to a different type...
MyInterface myItf = MyClass as MyInterface;
Actually, it does.
As of Mid-2022, the current version of C# has full support for so-called static abstract members:
interface INumber<T>
{
static abstract T Zero { get; }
}
struct Fraction : INumber<Fraction>
{
public static Fraction Zero { get; } = new Fraction();
public long Numerator;
public ulong Denominator;
....
}
Please note that depending on your version of Visual Studio and your installed .NET SDK, you'll either have to update at least one of them (or maybe both), or that you'll have to enable preview features (see Use preview features & preview language in Visual Studio).
See more:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members
https://blog.ndepend.com/c-11-static-abstract-members/
https://khalidabuhakmeh.com/static-abstract-members-in-csharp-10-interfaces#:~:text=Static%20abstract%20members%20allow%20each,like%20any%20other%20interface%20definition.
Regarding static methods used in non-generic contexts I agree that it doesn't make much sense to allow them in interfaces, since you wouldn't be able to call them if you had a reference to the interface anyway. However there is a fundamental hole in the language design created by using interfaces NOT in a polymorphic context, but in a generic one. In this case the interface is not an interface at all but rather a constraint. Because C# has no concept of a constraint outside of an interface it is missing substantial functionality. Case in point:
T SumElements<T>(T initVal, T[] values)
{
foreach (var v in values)
{
initVal += v;
}
}
Here there is no polymorphism, the generic uses the actual type of the object and calls the += operator, but this fails since it can't say for sure that that operator exists. The simple solution is to specify it in the constraint; the simple solution is impossible because operators are static and static methods can't be in an interface and (here is the problem) constraints are represented as interfaces.
What C# needs is a real constraint type, all interfaces would also be constraints, but not all constraints would be interfaces then you could do this:
constraint CHasPlusEquals
{
static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}
T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
foreach (var v in values)
{
initVal += v;
}
}
There has been lots of talk already about making an IArithmetic for all numeric types to implement, but there is concern about efficiency, since a constraint is not a polymorphic construct, making a CArithmetic constraint would solve that problem.
Because interfaces are in inheritance structure, and static methods don't inherit well.
What you seem to want would allow for a static method to be called via both the Type or any instance of that type. This would at very least result in ambiguity which is not a desirable trait.
There would be endless debates about whether it mattered, which is best practice and whether there are performance issues doing it one way or another. By simply not supporting it C# saves us having to worry about it.
Its also likely that a compilier that conformed to this desire would lose some optimisations that may come with a more strict separation between instance and static methods.
You can think of the static methods and non-static methods of a class as being different interfaces. When called, static methods resolve to the singleton static class object, and non-static methods resolve to the instance of the class you deal with. So, if you use static and non-static methods in an interface, you'd effectively be declaring two interfaces when really we want interfaces to be used to access one cohesive thing.
To give an example where I am missing either static implementation of interface methods or what Mark Brackett introduced as the "so-called type method":
When reading from a database storage, we have a generic DataTable class that handles reading from a table of any structure. All table specific information is put in one class per table that also holds data for one row from the DB and which must implement an IDataRow interface. Included in the IDataRow is a description of the structure of the table to read from the database. The DataTable must ask for the datastructure from the IDataRow before reading from the DB. Currently this looks like:
interface IDataRow {
string GetDataSTructre(); // How to read data from the DB
void Read(IDBDataRow); // How to populate this datarow from DB data
}
public class DataTable<T> : List<T> where T : IDataRow {
public string GetDataStructure()
// Desired: Static or Type method:
// return (T.GetDataStructure());
// Required: Instantiate a new class:
return (new T().GetDataStructure());
}
}
The GetDataStructure is only required once for each table to read, the overhead for instantiating one more instance is minimal. However, it would be nice in this case here.
FYI: You could get a similar behavior to what you want by creating extension methods for the interface. The extension method would be a shared, non overridable static behavior. However, unfortunately, this static method would not be part of the contract.
Interfaces are abstract sets of defined available functionality.
Whether or not a method in that interface behaves as static or not is an implementation detail that should be hidden behind the interface. It would be wrong to define an interface method as static because you would be unnecessarily forcing the method to be implemented in a certain way.
If methods were defined as static, the class implementing the interface wouldn't be as encapsulated as it could be. Encapsulation is a good thing to strive for in object oriented design (I won't go into why, you can read that here: http://en.wikipedia.org/wiki/Object-oriented). For this reason, static methods aren't permitted in interfaces.
Static classes should be able to do this so they can be used generically. I had to instead implement a Singleton to achieve the desired results.
I had a bunch of Static Business Layer classes that implemented CRUD methods like "Create", "Read", "Update", "Delete" for each entity type like "User", "Team", ect.. Then I created a base control that had an abstract property for the Business Layer class that implemented the CRUD methods. This allowed me to automate the "Create", "Read", "Update", "Delete" operations from the base class. I had to use a Singleton because of the Static limitation.
Most people seem to forget that in OOP Classes are objects too, and so they have messages, which for some reason c# calls "static method".
The fact that differences exist between instance objects and class objects only shows flaws or shortcomings in the language.
Optimist about c# though...
OK here is an example of needing a 'type method'. I am creating one of a set of classes based on some source XML. So I have a
static public bool IsHandled(XElement xml)
function which is called in turn on each class.
The function should be static as otherwise we waste time creating inappropriate objects.
As #Ian Boyde points out it could be done in a factory class, but this just adds complexity.
It would be nice to add it to the interface to force class implementors to implement it. This would not cause significant overhead - it is only a compile/link time check and does not affect the vtable.
However, it would also be a fairly minor improvement. As the method is static, I as the caller, must call it explicitly and so get an immediate compile error if it is not implemented. Allowing it to be specified on the interface would mean this error comes marginally earlier in the development cycle, but this is trivial compared to other broken-interface issues.
So it is a minor potential feature which on balance is probably best left out.
The fact that a static class is implemented in C# by Microsoft creating a special instance of a class with the static elements is just an oddity of how static functionality is achieved. It is isn't a theoretical point.
An interface SHOULD be a descriptor of the class interface - or how it is interacted with, and that should include interactions that are static. The general definition of interface (from Meriam-Webster): the place or area at which different things meet and communicate with or affect each other. When you omit static components of a class or static classes entirely, we are ignoring large sections of how these bad boys interact.
Here is a very clear example of where being able to use interfaces with static classes would be quite useful:
public interface ICrudModel<T, Tk>
{
Boolean Create(T obj);
T Retrieve(Tk key);
Boolean Update(T obj);
Boolean Delete(T obj);
}
Currently, I write the static classes that contain these methods without any kind of checking to make sure that I haven't forgotten anything. Is like the bad old days of programming before OOP.
C# and the CLR should support static methods in interfaces as Java does. The static modifier is part of a contract definition and does have meaning, specifically that the behavior and return value do not vary base on instance although it may still vary from call to call.
That said, I recommend that when you want to use a static method in an interface and cannot, use an annotation instead. You will get the functionality you are looking for.
Static Methods within an Interface are allowed as of c# 9 (see https://www.dotnetcurry.com/csharp/simpler-code-with-csharp-9).
I think the short answer is "because it is of zero usefulness".
To call an interface method, you need an instance of the type. From instance methods you can call any static methods you want to.
I think the question is getting at the fact that C# needs another keyword, for precisely this sort of situation. You want a method whose return value depends only on the type on which it is called. You can't call it "static" if said type is unknown. But once the type becomes known, it will become static. "Unresolved static" is the idea -- it's not static yet, but once we know the receiving type, it will be. This is a perfectly good concept, which is why programmers keep asking for it. But it didn't quite fit into the way the designers thought about the language.
Since it's not available, I have taken to using non-static methods in the way shown below. Not exactly ideal, but I can't see any approach that makes more sense, at least not for me.
public interface IZeroWrapper<TNumber> {
TNumber Zero {get;}
}
public class DoubleWrapper: IZeroWrapper<double> {
public double Zero { get { return 0; } }
}
As per Object oriented concept Interface implemented by classes and
have contract to access these implemented function(or methods) using
object.
So if you want to access Interface Contract methods you have to create object. It is always must that is not allowed in case of Static methods. Static classes ,method and variables never require objects and load in memory without creating object of that area(or class) or you can say do not require Object Creation.
Conceptually there is no reason why an interface could not define a contract that includes static methods.
For the current C# language implementation, the restriction is due to the allowance of inheritance of a base class and interfaces. If "class SomeBaseClass" implements "interface ISomeInterface" and "class SomeDerivedClass : SomeBaseClass, ISomeInterface" also implements the interface, a static method to implement an interface method would fail compile because a static method cannot have same signature as an instance method (which would be present in base class to implement the interface).
A static class is functionally identical to a singleton and serves the same purpose as a singleton with cleaner syntax. Since a singleton can implement an interface, interface implementations by statics are conceptually valid.
So it simply boils down to the limitation of C# name conflict for instance and static methods of the same name across inheritance. There is no reason why C# could not be "upgraded" to support static method contracts (interfaces).
An interface is an OOPS concept, which means every member of the interface should get used through an object or instance. Hence, an interface can not have static methods.
When a class implements an interface,it is creating instance for the interface members. While a static type doesnt have an instance,there is no point in having static signatures in an interface.

Creating objects of different Types using a unified Signature

Imagine the following two classes:
class A
{
public A()
{
}
}
class B : A
{
public B()
{
}
}
Is it possible for me to define A, or alternatively an interface, in a way that forces class B to have a parameterless constructor? Or, more generalized, a constructor (or static method) that is able to create an instance of type B with a given signature?
I do not want to restrict class B to only be constructible using that signature, but I want to be sure that class B can be constructed with this signature (be it parameterless, or specifying certain parameters).
To be clear: I am not searching for a solution that would require me to use Reflection or any other method to figure that out at runtime (I don't have a problem with it, but it would make the code less readable, and generally seems like a bad idea in this case).
Is there a way to accomplish this?
I wrote a blog post that goes more in-depth about what I am trying to achieve here
There is no interface or base type that you can apply to the type to ensure it has a parameterless constructor. The only context in which you can make such a contraint is generic constraints:
public static void Foo<T>()
where T : new() {}
In such a case the only types that can be used with Foo must have a parameterless constructor.
You can define factory for instantiating objects of type A (and derived types):
interface IFactory<T> where T : A
{
T Create(int i);
T Create(string s);
// and so on...
}
and require factory implementation, when you want to create an object.
This will make sure calling code in compile time, that it tries to create an object with the given set of parameters.
Of course, there's nothing preventing from NotImplementedException from concrete IFactory<T> implementation at run-time.
This is a followup, since I did a little bit of research and at least managed to come up with an answer that is somewhat satisfying.
So after digging around a while and trying to figure out how the built-in serialization/deserialization in C# works, I found out that C# has a method called GetUninitializedObject(). This method seems like a hack, since it just avoids calling the constructor of the object in the first place, but it at least gives me a way to accomplish what I originally wanted: Being able to deserialize an object of an arbitrary type. Using this, I am able to use methods on the uninitialized created objects (and forcing their implementation via an interface).
I find this to be fitting my needs, although it does not do what I originally wanted to, it allows me to implement a pattern that works for my purposes.
Best Regards

Using The Interface Methods I Want Based On The Implementation

I have two basic interface-related concepts that I need to have a better
understanding of.
1) How do I use interfaces if I only want to use some of the interface
methods in a given class? For example, my FriendlyCat class inherits from
Cat and implements ICatSounds. ICatSounds exposes MakeSoftPurr() and
MakeLoudPurr() and MakePlayfulMeow(). But, it also exposes MakeHiss()
and MakeLowGrowl() - both of which I don't need for my FriendlyCat class.
When I try to implement only some of the methods exposed by the interface
the compiler complains that the others (that I don't need) have not been
implemented.
Is the answer to this that I must create an interface that only contains
the methods that I want to expose? For example, from my CatSounds class, I
would create IFriendlyCatSounds? If this is true, then what happens when
I want to use the other methods in another situation? Do I need to create
another custom-tailored interface? This doesn't seem like good design to me.
It seems like I should be able to create an interface with all of the
relevant methods (ICatSounds) and then pick and choose which methods I
am using based on the implementation (FriendlyCat).
2) My second question is pretty basic but still a point of confusion for
me. When I implement the interface (using Shift + Alt + F10) I get the interface's
methods with "throw new NotImplementedException();" in the body. What
else do I need to be doing besides referencing the interface method that
I want to expose in my class? I am sure this is a big conceptual oops, but
similar to inheriting from a base class, I want to gain access to the methods
exposed by the interface wihtout adding to or changing them. What is the
compiler expecting me to implement?
-- EDIT --
I understand #1 now, thanks for your answers. But I still need further elaboration
on #2. My initial understanding was that an interface was a reflection of a the fully
designed methods of a given class. Is that wrong? So, if ICatSounds has
MakeSoftPurr() and MakeLoudPurr(), then both of those functions exist in
CatSounds and do what they imply. Then this:
public class FriendlyCat: Cat, ICatSounds
{
...
public void ICatSounds.MakeLoudPurr()
{
throw new NotImplementedException();
}
public void ICatSounds.MakeSoftPurr()
{
throw new NotImplementedException();
}
}
is really a reflection of of code that already exists so why am
I implementing anything? Why can't I do something like:
FriendlyCat fcat = new FriendlyCat();
fcat.MakeSoftPurr();
If the answer is, as I assume it will be, that the method has no
code and therefore will do nothing. Then, if I want these methods
to behave exactly as the methods in the class for which the interface
is named, what do I do?
Thanks again in advance...
An interface is a contract. You have to provide at least stubs for all of the methods. So designing a good interface is a balancing act between having lots of little interfaces (thus having to use several of them to get anything done), and having large, complex interfaces that you only use (or implement) parts of. There is no hard an fast rule for how to choose.
But you do need to keep in mind that once you ship your first version of the code, it becomes a lot more difficult to change your interfaces. It's best to think at least a little bit ahead when you design them.
As for implementation, it's pretty common to see code that stubs the methods that aren't written yet, and throws a NotImplemented exception. You don't really want to ship NotImplemented in most cases, but it's a good get around the problem of not having the code compile because you havn't implemented required parts of the interface yet.
There's at least one example in the framework of "deliberately" not implementing all of an interface's contract in a class: ReadOnlyCollection<T>
Since this class implements IList<T>, it has to have an "Insert" method, which makes no sense in a read-only collection.
The way Microsoft have implemented it is quite interesting. Firstly, they implement the method explicitly, something like this:
public class ReadOnlyCollection<T> : IList<T>
{
public void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
/* ... rest of IList<T> implemented normally */
}
This means that users of ReadOnlyCollection<T> don't see the Insert method in intellisense - they would only see it if it were cast to IList<T> first.
Having to do this is really a hint that your interface hierarchy is a bit messed up and needs refactoring, but it's an option if you have no control over the interfaces (or need backwards compatibility, which is probably why MS decided to take this route in the framework).
You have to implement all the methods in your interface. Create two interfaces, IHappyCatSounds and IMeanCatSounds, split out those methods. Don't implement IMeanCatSounds in FriendlyCat, because a friendly cat is not a mean cat. You have to think about an interface as a contract. When you write the interface, you are guaranteeing that every class that implements the interface will have those members.
It throws a NotImplementedException because you haven't implemented it yet. The compiler is expecting you to implement the code that would be completed when the cat purrs, meows or hisses. An interface doesn't have code in it. It's simply nothing more than a contract for any class that implements it, so you can't really "access the code" the interface implements, because the interface doesn't implement any code. You implement the code when you inherit from the interface.
For example:
// this is the interface, or the "contract". It guarantees
// that anything that implements IMeowingCat will have a void
// that takes no parameters, named Meow.
public class IMeowingCat
{
void Meow();
}
// this class, which implements IMeowingCat is the "interface implementation".
// *You* write the code in here.
public class MeowingCat : IMeowingCat
{
public void Meow
{
Console.WriteLine("Meow. I'm hungry");
}
}
I'd strongly suggest picking up a copy of The Object Oriented Thought Process, and read it through in it's entirety. It's short, but it should help you to clear things up.
For starters, though, I'd read this and this.
Imagine that you could "pick and choose." For example, suppose you were allowed to not implement ICatSounds.MakeHiss() on FriendlyCat. Now what happens when a user of your classes writes the following code?
public ICatSounds GetCat()
{
return new FriendlyCat();
}
ICatSounds cat = GetCat();
cat.MakeHiss();
The compiler has to let this pass: after all, GetCat is returning an ICatSounds, it's being assigned to an ICatSounds variable and ICatSounds has a MakeHiss method. But what happens when the code runs? .NET finds itself calling a method that doesn't exist.
This would be bad if it were allowed to happen. So the compiler requires you to implement all the methods in the interface. Your implementation is allowed to throw exceptions, such as NotImplementedException or NotSupportedException, if you want to: but the methods have to exist; the runtime has to be able to at least call them, even if they blow up.
See also Liskov Substitution Principle. Basically, the idea is that if FriendlyCat is an ICatSounds, it has to be substitutable anywhere an ICatSounds is used. A FriendlyCat without a MakeHiss method is not substitutable because users of ICatSounds could use the MakeHiss method but users of FriendlyCat couldn't.
A few thoughts:
Interface Separation Principle. Interfaces should be as small as possible, and only contain things that cannot be separated. Since MakePlayfulMeow() and MakeHiss() are not intrinsically tied together, they should be on two separate interfaces.
You're running into a common problem with deep inheritance trees, especially of the type of inheritance that you're describing. Namely, there's commonly three objects that have three different behaviors in common, only none of them share the same set. So a Lion might Lick() and Roar(), a Cheetah might Meow() and Lick(), and an AlienCat might Roar() and Meow(). In this scenario, there's no clear inheritance hierarchy that makes sense. Because of situations like these, it often makes more sense to separate the behaviors into separate classes, and then create aggregates that combine the appropriate behaviors.
Consider whether that's the right design anyway. You normally don't tell a cat to purr, you do something to it that causes it to purr. So instead of MakePlayfulMeow() as a method on the cat, maybe it makes more sense to have a Show(Thing) method on the cat, and if the cat sees a Toy object, it can decide to emit an appropriate sound. In other words, instead of thinking of your program as manipulating objects, think of your program as a series of interactions between objects. In this type of design, interfaces often end up looking less like 'things that can be manipulated' and more like 'messages that an object can send'.
Consider something closer to a data-driven, discoverable approach rather than a more static approach. Instead of Cat.MakePlayfulMeow(), it might make more sense to have something like Cat.PerformAction(new PlayfulMeowAction()). This gives an easy way of having a more generic interface, which can still be discoverable (Cat.GetPossibleActions()), and helps solve some of the 'Lions can't purr' issues common in deep inheritance hierarchies.
Another way of looking at things is to not make interfaces necessarily match class definitions 1:1. Consider a class to define what something is, and an interface as something to describe its capabilities. So whether FriendlyCat should inherit from something is a reasonable question, but the interfaces it exposes should be a description of its capabilities. This is slightly different, but not totally incompatible, from the idea of 'interfaces as message declarations' that I suggested in the third point.

How to design a inherited collection

I'm writing a program in C# that has a custom collection. The custom collection performs some useful aggregate functions (AllSuccessful, %Successful, etc) over it's members which are of type ResultInfo. I have several classes that derive from ResultInfo (UploadResultInfo, XUploadResultInfo, and YUploadResultInfo), and would like to have additional collections that inherit from ResultInfoCollection that have additional aggregate functions. The only problem with doing this as specified is that it leaves a useless
public void Add(ResultInfo item)
{
}
on the collection. Clarification: This method takes an argument of type ResultInfo, but a ResultInfo added to an UploadResultInfoCollection will throw an error. Is there an elegant way of solving my problem? I've considered generics but I don't quite know how that would work.
To define a generic class that handles any child of ResultInfo you just define it like
public class MyCollection<T> : ICollection<T>
where T : ResultInfo
{
... the required methods ... just use "T" instead of "ResultInfo" ...
public void Add(T item) {}
}
Later on you can use it by
MyCollection<FooResultInfo> coll = new MyCollection<FooResultInfo>();
Just try using them, they are not too difficult and learning by doing is the best way ...
I'm not sure how you are left with a useless Add method.
If the collection populates itself, you can make the Add method private.
If you want your "inherited" additional collections to not expose the Add method, use composition instead of inheritance.
Consider whether your useful methods actually need to be instance methods.
Do they need to maintain state when other operations happen or are they all possible using the publically avaialable (or internaally available) API?
If so then simply make them static methods (extension methods is probably a good idea) and don't worry about inheritance. If the methods are meaningful on IEnumerable<T> then so much the better, by doing this you make your utility functions vastly more usable and thus useful.
Using the resulting package of functions simply requires importing the relevant namespace.
If all you're doing is providing some extra methods to an otherwise existing collection type, then consider simply defining extension methods for that type and using a normal generic collection.

Categories