I'm used to instantiate object as following:
type obj-name = new type();
and now I'm using
IList<string> str_element = new List<string>();
I was expecting to see something
IList<string> actors = new IList<string>();
can somebody give me some ideas why for interface instantiation is different here?
Thanks,
Amit
An interface is just that — an interface, or a specification of what methods should exist.
An interface does not contain any actual code.
Interfaces can only be used as types that hold concrete classes.
It doesn't make sense to create an instance of an interface, since there is nothing to instantiate.
The reason you can't do = new IList<string>() is because IList<T> is an interface and you can't initialize interfaces as there is no body of code to call. I would reccomend doing
List<string> actors = new List<string>()
instead.
Interfaces define a contract, or set of functionality, that implementing classes must provide (at a minimum). By defining a variable of type IList<T>, you are really saying, "I don't care what the actual implementation is, it just needs to provide that functionality." This means you are divorcing the 'interface' and the 'implementation' in your calling code, which is a good thing.
The real power of interfaces is where you have pluggable code. If you were defining a library, rather than returning a List<T> instance, you could return an IList<T> instance (which AFAIK, is what the LINQ functionality does). This allows you to change the internal implementation of the object returned (it might be a linked list, or a B-Tree, or whatever), and calling code doesn't need to change.
Alot of the mocking libraries out there (e.g. NMock, Moq, etc) take advantage of interfaces and can generate implementing classes for testing purposes.
You can use LINQ: for example
This will give you something of a more Concrete Type.
using System.Linq;
IList<Foo> list = new List<Foo>();
IEnumerable<Foo> sortedEnum = list.OrderBy(f=>f.Bar);
IList<Foo> sortedList = sortedEnum.ToList()
Related
I'm testing a method which takes IList<T> where T: class, new(). For brevity, I'd like to test it with a type from the .NET standard library. However, I can't think of any which meet the conditions! Except for List<List<T>> - which I'd rather not use because manipulating collections of collections makes the test difficult to read.
Can you think of a type that meets the conditions? I don't want to add any new references.
How about List<object> or object[] ?
There are many classes that can be used although the best for you would be to create a small private class in your test class.
Simplest way would be using object-s:
var v1 = new object();
var v2 = new object();
If you want something that can be identified easier, you could use System.Version.
Just in case you're missing what this means, you can provide any IList implementation that contains a T. T must be a class, and must have a parameterless constructor so it could be any one of many classes, an object (as Marc pointed out, this is by far the simplest) or a System.Windows.Forms.Button or a SqlConnection.
Just create a new List<object>, List<Button> or a List<SqlConnection> to use any of these examples.
I haven't quite got my head around interfaces so thought I'd word the question in a way that'd help me better understand it.
I'm following a tutorial which has had me make an IQueryable. Why couldn't I just make a Queryable?
Queryable is just a static class that contains extension methods to the IQueryable<T> interface. You wouldn't use Queryable directly in your code but rather invoke its methods given an IQueryable<T> instance.
Queryable is a static class that provides some convenient and useful methods to anything implementing IQueryable. You can't make it because it's already made. You need to make a new class that actually does what you want it to do, and implement IQueryable so other code written to use IQueryable (including Queryable) knows how to use it.
An interface is a contract that defines methods and properties, but there is no implementation in an interface.
A class implements the interface by supplying implementation for everything that is defined in the interface.
As an interface has no implementation, you can't create an instance of one. You have to create an instance of a class that implements the interface.
However, you can have a reference of the interface type, but it will point to an actual object. When you use the interface reference, you can use everything that is defined in the interface, but if the class contains more methods, you can't reach them without casting the reference to the actual class.
An interface does not imply how the class will be coded, only how the interaction with that class will be defined.
There may be many different implementations of a class that can query but that's unimportant as long as the interaction with all of those classes is the same.
I'm writing an interface that will be implemented by a lot of classes, and I'm writing a class that will hold a collection of instances of these implementations. Every class will have a default constructor.
So, is there a simple way (e.g. using some kind of reflection) to put an instance of each of these implementing classes to the collection? Besides doing it manually, which is simple, yes, but a lot of work and error prone (what if I missed an implementation while writing the method? What if a new implementation came and I forgot to update the given method?).
So, what I would like is to be able to iterate through all classes of a given namespace or maybe through the list of all available classes. My method then would simply check, through reflection, if the given class implements the given interface, and if it does, puts it into the collection.
Thank you.
You need to call Assembly.GetTypes() to get every class in an assembly, call typeof(IMyInterface).IsAssignableFrom to check for classes that implement the interface, then call Activator.CreateInstanse to instantiate the class.
Using LINQ:
typeof(IMyInterface).Assembly.GetTypes()
.Where<Type, bool>(typeof(IMyInterface).IsAssignableFrom)
.Select(t => Activator.CreateInstance(typeof(T)))
.ToArray()
Here it is without LinQ, spread out so you can see what's going on. But otherwise it's exactly the same as what SLaks wrote.
It get's all classes implementing the interface IFoo.
List<IFoo> items = new List<IFoo>();
//Iterate through all types
foreach (Type type in Assembly.GetExecutingAssembly.GetTypes) {
//Check the type is public and not abstract
if (!type.IsPublic | type.IsAbstract)
continue;
//Check if it implements the interface IFoo
if (typeof(IFoo).IsAssignableFrom(type)) {
//Create an instance of the class
//If the constructor has arguments put them after "type" like so:
//Activator.CreateInstance(type, arg1, arg2, arg3, etc...)
IFoo foo = (IFoo)Activator.CreateInstance(type);
//Add the instance to your collection
items.Add(foo);
}
}
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
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).