Purpose of IDictionary interface - c#

What is the need of IDictionary interface. How can IDictionary interface be initialized. After all it is just an interface. The following code snippet is from msdn. I could not understand it.
IDictionary<string, string> openWith = new Dictionary<string, string>();

It defines the important functions that an Dictionary should implement.
The line from MSDN means that you are creating an object openWith which implements the functions (methods) defined in IDictionary interface.
When you use Dictionary to declare the variable like:
Dictionary<string,string> openWith=.....;
you are bind with the concrete type of object. But when you use
IDictionary<string,string> openWith=....;
you can use it with any object that implements IDictionary interface, maybe your own custom class :)

The whole point of interfaces is to provide... well, an interface to whatever module (I use "module" in a broad sense here) so that calling code will not have to worry about how this particular interface is implemented.
As for "How can IDictionary interface be initialized", this is technically not correct. What can be initialized is a variable, whose type is IDictionary<T, V>. Sure enough variables have to be initialized, but that's usually hidden from the "client code".
IDictionary is not very representative, however. Rather, consider an IDataReader interface. You've surely dealt with ADO.NET, so this should look familiar:
public Foo PopulateFromDataReader(SqlDataReader dataReader)
This particular method is tightly coupled to an SqlDataReader, so you'd have to rewrite it for it to support, say, Access or Oracle or MySQL or Firebird or whatever. In other words, you depend on implementation.
Now consider:
public Foo PopulateFromDataReader(IDataReader dataReader)
This method can be used with whatever class that implements IDataReader, which means with basically any ADO.NET-compatible data provider.

It would be no different to any other interface. Try thinking about a simpler example:
interface IThermometer
{
double CurrentTemperature { get; }
}
Now we have a way to get the temperature, though we don't care exactly how it's measured. We can create various implementations:
class MercuryThermometer : IThermometer
{
public double CurrentTemperature
{
get { return ... /* gets the temperature somehow */ }
}
}
The rest of the program doesn't need to know which thermometer it's using.

I suspect you've simply overlooked the difference between the variable typed as IDictionary<,> (the interface), and the value (reference) initialized as a Dictionary<,> (note no I; the concrete type).

It's also useful for unit testing. You can write a unit test for a method that accepts an IDictionary instead of a Dictionary and pass a mock. If it were to accept a class instance (which could also be sealed) you'd be a little screwed (you'd have to use the adapter pattern and so on).

Related

IReadOnlyCollection vs ReadOnlyCollection

There are a couple of similar questions already on SO, but none of the ones I found really touches on this particular topic, so here it goes...
My understanding is that one should always attempt to return an interface over a concrete class. Won't go into the reasons behind it, plenty of things on SO about that already.
However in the case of an IReadOnlyCollection vs a ReadOnlyCollection I'm not sure if that rule should be followed.
An IReadOnlyCollection can be easily cast into a List, which... well... breaks the ReadOnly aspect that the contract promises.
ReadOnlyCollection however cannot be cast into a List, but it means returning a concrete class.
In the long run, does it actually matter? It seems to me like in most cases a ReadOnly*/IReadOnly* object is only returned returned by either a method or a read-only property.
So even if the user decides to cast it to something else (in the case of a IReadOnly* object) or use LINQ to create a collection of some kind out of it (in the case of ReadOnly* object), there's really no way that the class exposing the ReadOnly*/IReadOnly* object is going to accept that back.
So what's the recommendation here, return an IReadOnly* interface or a concrete ReadOnly* class instance?
IReadOnlyCollection<T> can only be cast to List<T> if the underlying object is of that type. ReadOnlyCollection<T> for example also implements IReadOnlyCollection<T>.
So my recommendation, return IReadOnlyCollection<T> and if you are worried that caller would wrongly cast it to something it shouldn't, make sure the underlying type is ReadOnlyCollection<T>
public IReadOnlyCollection<User> GetUsers()
{
return new ReadOnlyCollection<User>();
}
But returning IReadOnlyCollection<T> should be enough for caller of function to understand it is supposed to be read only. Note that you can never completely secure your code with a ReadOnlyCollection<T>, caller can still use reflection to access the internal list and manipulate it.
The only option in that case would be to create a copy if the list and return that.
You definitely should attempt to make your public methods return interfaces.
If you're afraid that your class's callers are going to cast and modify your internal structures, such as in this example, where a class's internal queue shouldn't be touched from the outside:
public class QueueThing
{
private List<QueueItem> _cantTouchThis;
public IReadOnlyCollection<QueueItem> GetQueue()
{
return _cantTouchThis;
}
}
Then you could use AsReadOnly() to return a new ReadOnlyList<T>, sourced from the private List<T>:
public class QueueThing
{
private List<QueueItem> _cantTouchThis;
public IReadOnlyCollection<QueueItem> GetQueue()
{
return _cantTouchThis.AsReadOnly();
}
}
Now the caller can cast the returned value all they want, they won't be able to modify the _cantTouchThis member (except of course when they're going to use reflection, but then all bets are off anyway).
Given many types can implement an interface, a user of such a method should definitely not assume that it's safe to cast the return value of the method to any concrete type.
Microsoft's guidelines here state:
✓ DO use ReadOnlyCollection, a subclass of ReadOnlyCollection<T>, or in rare cases IEnumerable<T> for properties or return values representing read-only collections.
So, basically, you should return ReadOnlyCollection<T>. It specifies interface IEnumerable in other cases, so if it intended interface IReadOnlyCollection<T>, it would have stated so.

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.

When to use variable of Interface type rather than concrete type

I have a class which derives from an Interface. Now the class has to implement all the methods in the Interfaces + it additionally defines 2 more methods.
Now my question is , what is the benefit/usecases of doing this:
IMyInterface varInt= new ConcreteImp();
over,
ConcreteImp varInt= new ConcreteImp();
I see this pattern used every where in code blocks, but not sure why this is used.
Benefit in using interfaces is in decreasing dependency of parts on concrete implementation of a software component. In one line you posted, you won't be able to see a benefit. Benefit can be gained in consumers of that interface.
Edit: You would be well to read this article on abstractions.
For example, lets say that you have a method which accepts an interface like so Rent(IMovie). Another person will be able to write implementation of Rent() method without knowing specifics of IMovie type which you will pass in when calling the method. You will then be able to create multiple different IMovie implementations which may have different method of billing, but Rent() method doesn't have to take care of that.
void Rent(IMovie movie)
{
var price = movie.Price();
movie.MarkReserved();
}
public interface IMovie { }
public class Oldie : IMovie
{
private decimal _oldieRate = 0.8;
public decimal Price()
{
return MainData.RentPrice * _oldieRate;
}
public decimal MarkReserved()
{
_oldiesDb.MarkReserved(this, true);
}
}
public class Blockbuster : IMovie
{
private decimal _blockbusterRate = 1.2;
public decimal Price()
{
return MainData.RentPrice * _blockbusterRate ;
}
public decimal MarkReserved()
{
_regularDb.MarkReserved(this, true);
}
}
This is example of why interfaces are useful, but is not very nice example of code design.
As a rule of thumb, you should write methods so that they require least input they need to work, and that their output provides as much information for others to use when they call it. For example, take a look at following signature:
public List<Entity> Filter(IEnumerable<Entity> baseCollection){ ... }
This method requests only IEnumerable<Entity> so it can take different collection types, like List<Entity>, Entity[] or custom types some tool returns. But you return List<Entity> so that right away you are not limiting caller to just enumerable elements. She can use Linq on return value right away for example.
There are more benefits, like in unit testing, where you can create mock objects and tell them how to behave during interaction with rest of the code. Although, you can do this with classes with virtual methods now.
Suppose that you want, elsewhere in the code, to be able to assign a different implementation of IMyInterface to the varInt variable. Then that variable needs to be declared with type IMyInterface.
Alternatively, if you want to make it clear to any code readers that all you intend to do with varInt is use the interface defined by IMyInterface, then the type declaration makes that clear.
When you need to enforce functionality in the derived class use interface.
and when you need to pass data from super class to subclass then you use concrete class. Its the basic oop idea behind interface and subclass.
In your concrete example I would say it doesn't matter as much since you are using new and creates a concrete type. When you start using dependency injection it starts to be more useful.
A scenario where it is more useful looks like the following:
public SomeResultType DoSomething(ISomeType obj)
{
//to something with obj
// return someResultType
}
The above can be called using any type as long as it implements ISomeType. But in your example using the new keyword I would instead use var. You will still be able to treat it as type it implements since it inherit that type.
assume that IMyInterface have "Draw" method, now all derived classes have to implement "Draw" method. if you have a class "Engine" with a method "Render(IMyInterface shape)", you have only to call the "Draw" method no matter what the shape is. and every shape Draw itself as he wants.
you can take a look at Design Patterns and you can see the magic of interfaces ;)

Would .NET be able to function just as well without the use of type Object?

I am asking this because it seems like using Object seems to be an easy way out to solve certain problems, like "I don't have a specific type, so use Object", etc.
Also the reason this made me curious is because a colleague of mine told me that if .NET was a true object-oriented platform then it wouldn't have to have a catch all type like Object.
So if .NET didn't have the Object type, what would be the alternative ways to solve the occuring problems to make it function just the same?
Also just to note, this is not to bash .NET, as I use it daily in my work. Just want to know more about it.
EDIT: Another note I remembered is because the type Object exists, its effect ripples throughout the whole .NET. Like IEnumerable exists but also IEnumerable<T>. And in many situations you have to implement both the generic and non-generic version of things, etc.
I would say that the problem that is solved by Object is not "I don't have a specific type, so use Object", but rather "I don't really care what type this is; all I need to know it that it is an Object"
It is a convenience, not only for use as a 'generic' type but also for reflection, garbage collection etc.
Other languages (C++) can do without, but I would hesitate to say that makes those languages more OOP.
Your friend probably works with a dynamic language (like ruby or python), right?
There are a great many people who think that strongly typed languages should be referred to as "class oriented" rather then "object oriented", because all possible behaviors and polymorphism needs to be done up front in the class definition. When your method accepts anything, any any checks are done based off of the objects capabilities rather then its class, you could say that is a more object oriented approach.
I am sort of conflicted on this argument. There is this boneheaded belief in programming circles that OO is unequivocally Good, no matter what the problem or requirements. Because of that, people tend to try to win arguments by saying "such and such isn't object oriented", and since object oriented is a synonym for good, they win. Even though I think static languages are a pain to work with, I think calling them not OO is a disingenuous way to make your point. On the other hand, anything that will make a programmer reach outside his comfort zone and learn a new way to do something (if for no other reason then to win an argument) can't be totally bad. As I said, conflicted. :)
Remember that inheritance denotes an "is-a" relationship. Every class in .NET "is a(n)" object. They all have a ToString method. They all have a type, which you access through GetType. This sort of relationship and the resultant sharing of functionality is the basis of object-oriented programming.
In a strongly-typed framework, Objects have to start somewhere.
The type object is not there to provide an "easy" catch-all casting option, or to force you to cast down to the lowest common denominator. It is there to provide the absolute most general case for an object- a basis for reference comparison and a handy ToString() method, among a few others.
Yes object type can be misused, but it provides seminal functionality to the world of .NET (above all IMO is GetType()). So if there is a problem, it is not with having the type of object.
Alternatives are many, including Generics and OOP practices such as interfaces...
If the object derivation hierarchy didn't have a single unified head, then it would be impossible to test for equality between any two arbitrary...uh...things without resorting to dynamic typing.
Other than that, I suspect the functionality of object could have been handled just about as well by separate interfaces (IEqualable and IConvertableToString). On the other hand, object's virtual methods are pretty handy sometimes, especially ToString, which can be used by an IDE or debugger when displaying program state. It's really a pragmatic design.
I'm by no means particularly knowledgeable on this subject, but from my perspective it was useful to allow people to build polymorphic components without having prior knowledge of how those components would be consumed. What do I mean by that? Let me try to explain.
Let's take a simple example with the .NET framework's ArrayList class. This was part of the original framework, before Generics were introduced. The authors of the ArrayList class were trying to provide a useful dynamic list implementation, but they had no way of knowing what kinds of objects would be inserted into the list. They used the Object type to represent the items in the list because it would allow any type of class to be added to the list. For example:
ArrayList people = new ArrayList();
people.Add(new Doctor());
people.Add(new Lawyer());
people.Add(new PetDetective());
people.Add(new Ferrari()); // Yikes!
// ...
for (int i = 0; i < people.Count; i++)
{
object person = people[0];
// ...
}
Now, if this were your own application and you knew that your Doctor, Lawyer, and PetDetective classes all derived from a common Person base class, then you could, in theory, build your own linked list implementation based on the Person class rather than the Object class. However, that's a lot of extra work for very little benefit when you already have a built and tested ArrayList class. If you really want to make it specific to your Person base class, then you could always create a wrapper class for ArrayList that only accepts Person-derived objects.
In C++, you could do essentially the same thing using the "void pointer" data type (void*). However, C++ also supported templates (very similar to generics), which made it much easier to build a useful component without knowing the details of what other classes it would be used with. Since C# did not initally support generics, using the Object type was really the only way to build general polymorphic components for other people to use.
The idea that the concept of System.Object could be replaced by interfaces that, as a rule, all classes implement has been mentioned a few times on this question. While I think the idea is valid, in the end I would say that it doesn't buy you anything. Even if such interfaces existed, the question would still remain of how the compiler would actually ensure that classes implemented those interfaces.
Below is some example code where I try to explore a hypothetical situation where there is no System.Object type and how the implementation under the hood as well as usage of those interfaces might look.
// let's start off by defining interfaces to describe the various methods that are currently available from the System.Object class
public interface IEquatable
{
bool Equals(IEquatable other);
}
public interface IHashCodeGenerator
{
int GetHashCode();
}
public interface ITypeIdentifiable
{
Type GetType();
}
public interface IConvertibleToString
{
string ToString();
}
// This guy throws a wrench into things, because we can't privately (or "protectedly") implement an interface.
// This is discussed further below on the MyClass.MemberwiseClone method.
public interface IMemberwiseCloneable
{
}
// This class simply encapsulates similar functionality found within the System.Object class
public static class ClrInternals
{
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool Equals(IEquatable objA, IEquatable objB);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int GetHashCode(IHashCodeGenerator hashGenerator);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern Type GetType(ITypeIdentifiable typedInstance);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IMemberwiseCloneable MemberwiseClone(IMemberwiseCloneable original);
}
// let's say that as a rule the compiler implicitly makes all classes implement these interfaces
class MyClassExampleA : IEquatable, IHashCodeGenerator, ITypeIdentifiable, IConvertibleToString, IMemberwiseCloneable
{
// The compiler also implicitly makes all classes implement the interfaces with the following code (unless otherwise specified)
#region IEquatable Members
public bool Equals(IEquatable other)
{
// let's suppose that this is equivalent to the current implementation of Object.Equals
return ClrInternals.Equals(this, other);
}
#endregion
#region IHashCodeGenerator Members
public int GetHashCode()
{
// let's suppose that this is equivalent to the current implementation of Object.GetHashCode
return ClrInternals.GetHashCode(this);
}
#endregion
#region ITypeIdentifiable Members
public Type GetType()
{
// let's suppose that this is equivalent to the current implementation of Object.GetType
return ClrInternals.GetType(this);
}
#endregion
#region IConvertibleToString Members
public string ToString()
{
// let's suppose that this is equivalent to the current implementation of Object.ToString
return this.GetType().ToString();
}
#endregion
// this one is perhaps a little goofy, since it doesn't satisfy any interface
// In order to be equivalent to the current Object.MemberwiseClone implementation, I've made this protected,
// but we cannot have a protected method that implements an interface, so this throws a wrench into things.
protected MyClassExampleA MemberwiseClone()
{
// let's suppose that this is equivalent ot the current implementation of Object.MemberwiseClone
return (MyClassExampleA)ClrInternals.MemberwiseClone(this);
}
// ** All of the above code is just a representation of the implicit semantics that the compiler/CLR applies to a class. Perhaps this code is not actually generated by the compiler for each class (that would be a lot of duplication!), but rather the CLR might handle this logic internally
}
// Ok, so now I'm implementing a general Stack class
public class Stack
{
// what type should I use for the parameter?
// I have five different interfaces to choose from that I know all classes implement, but which one should I pick?
public void Push(type??? item)
{
// ...
}
// what type should I use for the return type?
// I have five interfaces to choose from, but if I return one,
// then my caller can't utilize the methods defined in the other interfaces without casting.
// I know all classes implement all five interfaces, but is it possible that my Stack might also contain non-class objects that don't implement all interfaces? In that case it might be dangerous for the caller to cast the return value from one interface to another.
public type??? Pop()
{
// ...
}
// In C++ I could have used void* or defined the Stack class as a template
}
// moving on...
class StackUtilizer
{
// here I try to utilize the Stack class
public void UseStack(Stack stack)
{
// what type should I use for the variable to hold the result of the Stack.Pop method?
type??? item = stack.Pop();
// if I use IEquatable
IEquatable item1 = stack.Pop();
IEquatable item2 = stack.Pop();
item1.Equals(item2); // then I can do this
Type itemType = item1.GetType(); // but I can't do this
string s = item1.ToString(); // nor can I do this
// Ok, this calls for another interface that composes all of these other interfaces into one
}
}
// let's define a single interface that pulls all of these other interfaces together
public interface IObject : IEquatable, IHashCodeGenerator, ITypeIdentifiable, IConvertibleToString, IMemberwiseCloneable
{
// no need to define any methods on this interface. The purpose of this interface is merely to consolidate all of these other basic interfaces together.
}
// now we change the compiler rule to say that all classes implicitly implement the IObject interface
class MyClassExampleB : IObject
{
// ... <refer to MyClassExampleA for the implicit implementation of the interfaces>
}
// now let's try implementing that Stack class again
public class Stack
{
// I know that all classes implement the IObject interface, so it is an acceptable type to use as a parameter
public void Push(IObject item)
{
// ...
}
// again, since all classes implement IObject, I can use it as the return type
public IObject Pop()
{
// ...
throw new NotImplementedException("This is an example. The implementation of this method is irrelevant.");
}
}
class StackUtilizer
{
// here I try to utilize the Stack class
public void UseStack(Stack stack)
{
// now I can just use IObject for my variables holding the return value of the Stack.Pop method
IObject item = stack.Pop();
// if I use IObject
IObject item1 = stack.Pop();
IObject item2 = stack.Pop();
item1.Equals(item2); // then I can do this
Type itemType = item1.GetType(); // and I can do this
string s = item1.ToString(); // and I can do this
}
}
So, in the end we still have an IObject interface, similar to the current System.Object class. The open question is how the compiler/CLR would handle enforcing our rule that all classes implement the IObject interface.
I can think of three possible approaches:
The compiler generates the implicit interface implementation for each class, which would cause a lot of duplication.
The CLR would handle those interface implementations in a special way that would not require the compiler to actually generate code for each class.
We define a base class, let's call it Object (starting to sound familiar?), that implements the IObject interface and we change the rule to say that all classes implicitly inherit from Object (this is exactly what we have today but without the interfaces).

A difference in style: IDictionary vs Dictionary

I have a friend who's just getting into .NET development after developing in Java for ages and, after looking at some of his code I notice that he's doing the following quite often:
IDictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>();
He's declaring dictionary as the Interface rather than the Class. Typically I would do the following:
Dictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>();
I'd only use the IDictionary interface when it's needed (say, for example to pass the dictionary to a method that accepts an IDictionary interface).
My question is: are there any merits to his way of doing things? Is this a common practice in Java?
If IDictionary is a "more generic" type than Dictionary then it makes sense to use the more generic type in declaring variables. That way you don't have to care as much about the implementing class assigned to the variable and you can change the type easily in the future without having to change a lot of following code. For example, in Java it's often considered better to do
List<Integer> intList=new LinkedList<Integer>();
than it is to do
LinkedList<Integer> intList=new LinkedList<Integer>();
That way I'm sure all following code treats the list as a List and not a LinkedList, making it easy in the future to switch out LinkedList for Vector or any other class which implements List. I'd say this is common to Java and good programming in general.
This practice isn't just limited to Java.
It's often used in .NET as well when you want to de-couple the instance of the object from the class you're using. If you use the Interface rather than the Class, you can change the backing type whenever needed without breaking the rest of your code.
You'll also see this practice used heavily with dealing with IoC containers and instanciation using the Factory pattern.
Your friend is following the very useful principle:
"Abstract yourself from implementation details"
You should always attempt to program to the interface rather than the concrete class.
In Java or any other object oriented programming language.
In .NET world is common to use an I to indicate that is an interface what your're using. I think this is more common because in C# they don't have implements and extends to refer class vs interface inheritance.
I think whey would type
class MyClass:ISome,Other,IMore
{
}
And you can tell ISome an IMore are interfaces while Other is a class
In Java there is no need for such a thing
class MyClass extends Other implements Some, More {
}
The concept still applies, you should try to code to the interface.
For local variables and private fields, which are already implementation details, it's better to use concrete types than interfaces for the declarations because the concrete classes offer a performance boost (direct dispatch is faster than virtual/interface dispatch). The JIT will also be able to more easily inline methods if you don't unnecessarily cast to interface types in the local implementation details. If an instance of a concrete type is returned from a method that returns an interface, the cast is automatic.
Most often, you see the interface type (IDictionary) used when the member is exposed to external code, whether that be outside the assembly or just outside the class. Typically, most developers use the concrete type internally to a class definition while they expose an encapsulated property using the interface type. In this way, they can leverage the concrete type's capabilities, but if they change the concrete type, the declaring class's interface doesn't need to change.
public class Widget
{
private Dictionary<string, string> map = new Dictionary<string, string>();
public IDictionary<string, string> Map
{
get { return map; }
}
}
later can become:
class SpecialMap<TKey, TValue> : IDictionary<TKey, TValue> { ... }
public class Widget
{
private SpecialMap<string, string> map = new SpecialMap<string, string>();
public IDictionary<string, string> Map
{
get { return map; }
}
}
without changing Widget's interface and having to change other code already using it.
IDictionary is an interface and Dictionary is a class.
Dictionary implements IDictionary.
That means that this is possible to refer to Dictionary instance with/by IDictionary instance and invoke most of the Dictionary methods and properties through IDictionary instance.
This is very recommended to use interfaces as many as possible, because interfaces abstracts the modules and assemblies of the applications, allows polymorphism, which is both very common and useful in many situations and cases and allows replacing one module by another without touching the other modules.
Suppose that in the present, the programmer wrote:
IDictionary<string> dictionary = new Dictionary<string>();
And now dictionary invokes the methods and properties of Dictionary<string>.
In the future the databases has been grown up in size and we find out that Dictionary<string> is too slow, so we want to replace Dictionary<string> by RedBlackTree<string>, which is faster.
So all what is needed to be done is replacing the above instruction to:
IDictionary<string> dictionary = new RedBlackTree<string>();
Of course that if RedBlackTree implements IDictionary then all the code of the application compiles successfully and you have a newer version of your application, where the application now performs faster and more efficient than the previous version.
Without interfaces, this replacement would be more difficult to do and would require the programmers and developers to change more code that is potential to bugs.
As far as I've seen Java developers tend to use abstraction (and design patterns) more often than .NET developers. This seems another example of it: why declare the concrete class when he'll essentially only be working with the interface members?
In the described situation almost every Java developer would use the interface to declare the variable. The way the Java collections are used is probably one of the best examples:
Map map = new HashMap();
List list = new ArrayList();
Guess it just accomplishes loose coupling in a lot of situations.
Java Collections include a multitude of implementations. Therefore, it's much easier for me to make use of
List<String> myList = new ArrayList<String>();
Then in the future when I realize I need "myList" to be thread safe to simply change this single line to
List<String> myList = new Vector<String>();
And change no other line of code. This includes getters/setters as well. If you look at the number of implementations of Map for example, you can imagine why this might be good practice. In other languages, where there is only a couple implementations for something (sorry, not a big .NET guy) but in Objective-C there is really only NSDictionary and NSMutableDictionary. So, it doesn't make as much sense.
Edit:
Failed to hit on one of my key points (just alluded to it with the getter/setters).
The above allows you to have:
public void setMyList(List<String> myList) {
this.myList = myList;
}
And the client using this call need not worry about the underlying implementation. Using whatever object that conforms to the List interface that they may have.
Coming from a Java world, I agree that the "program to an interface" mantra is drilled into you. By programming to an interface, not an implementation, you make your methods more extensible to future needs.
I've found that for local variables it generally doesn't much matter whether you use the interface or the concrete class.
Unlike class members or method signatures, there is very little refactoring effort if you decide to change types, nor is the variable visible outside its usage site. In fact, when you use var to declare locals, you are not getting the interface type but rather the class type (unless you explicitly cast to the interface).
However, when declaring methods, class members, or interfaces, I think that it will save you quite a bit of headache to use the interface type up front, rather than coupling the public API to a specific class type.
Using interfaces means that "dictionary" in the following code might be any implementation of IDictionary.
Dictionary1 dictionary = new Dictionary1();
dictionary.operation1(); // if operation1 is implemented only in Dictionary1() this will fail for every other implementation
It's best seen when you hide the construction of the object:
IDictionary dictionary = DictionaryFactory.getDictionary(...);
I've encountered the same situation with a Java developer. He instantiates collections AND objects to their interface in the same way.
For instance,
IAccount account = new Account();
Properties are always get/set as interfaces. This causes problems with serialization, which is explained very well here

Categories