IList<> returned type instead of List<> - asp.net-mvc

I found this method in one of examples for dependency Injecting a Controller. What is the reason of using an interface type IList<> instead of List<>?
public IList<string> GetGenreNames()
{
var genres = from genre in storeDB.Genres
select genre.Name;
return genres.ToList();
}

The actual reason, you're going to go ask the original programmer of that method that.
We can come up with a plausible reason however.
Input parameters should be as open and general as possible. Don't take an array if you can use any collection type that can be enumerated over. (ie. prefer IEnumerable<int> over List<int> if all you're going to do is do a foreach)
Output parameters and return types should be as specific as possible, but try to return the most usable and flexible data type possible without sacrificing performance or security. Don't return a collection that can only be enumerated over (like IEnumerable<int>) if you can return an array or a list you created specifically for the results (like int[] or List<int>).
These guidelines are listed many places on the internet (in different words though) and are there to help people write good APIs.
The reason why IList<T> is better than List<T> is that you're returning a collection that can be:
Enumerated over (streaming access)
Accessed by index (random access)
Modified (Add, Delete, etc.)
If you were to return List<T> you wouldn't actually add any value, except to return a concrete type instead of just any type that happens to implement that interface. As such, it is better to return the interface and not the concrete type. You don't lose any useful features on the outside and you still retain the possibility of replacing the actual object returned with something different in the future.

targeting interface is always better than targeting concrete type.
So if returning IList, that means anything implementing IList could be returned, give better separation.
check this out for more info
Why is it considered bad to expose List<T>?

It's somewhat basic rule in OOP. It's good to have an interface so your clients (the caller of GetGenreNames ) knows only how to call (function signature, only thing to remember, rather than implementation details etc) to get serviced.
Programming to interface supports all goodies of OOP. its more generalized, maintains separation of concerns, more reusable.

Related

What does it mean <> in method?

I have this method
#override
Response<BodyType> convertResponse<BodyType, SingleItemType>(
Response response) {
final Response dynamicResponse = super.convertResponse(response);
final BodyType customBody =
_convertToCustomObject<SingleItemType>(dynamicResponse.body);
return dynamicResponse.replace<BodyType>(body: customBody);
}
What does it mean <BodyType> and <BodyType, SingleItemType> in this method?
These are called generics in Dart (in fact, they are called the same in other similar programming languages).
The main idea behind generics is that you could reuse the same code without relying on a specific data/return type. Imagine List in Dart. You could have a list of integers (List<int>), a list of strings (List<String>), a list of your custom objects (List<CustomType>) - the type is not hardcoded and it could be adjusted based on your needs.
Also, you could say that it would be easier just to use dynamic or Object types that would cover most of these cases. However, generics brings you type safety, and the method type itself becomes a parameter.
Here is the official documentation about generics.

Why should i use TCollections.CreateList<T> and not TList<T>.Create

i added map(), reduce() and where(qlint : string) to a Spring4D fork of mine.
While i was programming these functions, i found out that there is a differnce in the behaviour of the lists, when they are created in different ways.
If i create them with TList<TSomeClass>.create the objects in the enumerables are of the type TSomeClass.
If i create them with TCollections.CreateList<TSomeClass> the objects in the enumerables are of the type TObject.
So the question is:
Is there a downside by using TList<TSomeClass>.create ?
Or in other words: Why should i use TCollections.CreateList<TSomeClass> ?
btw: with TCollections.CreateList i got a TObjectList and not a TList. So it should be called TCollections.CreateObjectList... but that's another story.
Depending on the compiler version many of the Spring.Collections.TCollections.Create methods are applying what the compiler is unable to: folding the implementation into only a very slim generic class. Some methods are doing that from XE on, some only since XE7 ( GetTypeKind intrinsic function makes it possible to do the type resolution at compile time - see the parameterless TCollections.CreateList<T> for example).
This greatly reduces the binary size if you are creating many different types of IList<T> (where T are classes or interfaces) because it folds them into TFolded(Object|Interface)List<T>. However via the interface you are accessing the items as what you specified them and also the ElementType property returns the correct type and not only TObject or IInterface. On Berlin it adds less than 1K for every different object list while it would add around 80K if the folding is not applied due to all the internal classes involved for the different operations you can call on an IList<T>.
As for TCollections.CreateList<T> returning an IList<T> that is backed by a TFoldedObjectList<T> when T is a class that is completely as designed. Since the OwnsObject was passed as False it has the exact same behavior as a TList<T>.
The Spring4D collections are interface based so it does not matter what class is behind an interface as long as it behaves accordingly to the contract of the interface.
Make sure that you only carry the lists around as IList<T> and not TList<T> - you can create them both ways (with the benefits I mentioned before when using the TCollections methods). In our own application some places are still using the constructor of the classes while many other places are using the static methods from Spring.Collections.TCollections.
BTW:
I saw the activity in your fork and imo there is no need to implement Map/Reduce because that is already there. Since the Spring4D collections are modelled after .NET they are called Select and Aggregate (see Spring.Collections.TEnumerable). They are not available on IEnumerable<T> directly though because interfaces must not have generic parameterized methods.

Semantics of OMG IDL attributes

I'm working on the verification of an interface formalised in the OMG's IDL, and am having problems finding a definitive answer on the semantics of getting an attribute value. In an interface, I have an entry...
interface MyInterface {
readonly attribute SomeType someName;
};
I need to know if it is acceptable for someObj.someName != someObj.someName to be true (where someObj is an instance of an object implementing MyInterface).
All I can find in OMG documentation in regards to attributes is...
(5.14) An attribute definition is logically equivalent to declaring a
pair of accessor functions; one to retrieve the value of the attribute
and one to set the value of the attribute.
...
The optional readonly keyword indicates that there is only a single
accessor function—the retrieve value function.
Ergo, I'm forced to conclude that IDL attributes need not be backed by a data member, and are free to return basically any value the interface deems appropriate. Can anyone with more experience in IDL confirm that this is indeed the case?
As we know, IDL interface always will be represented by a remote object. An attribute is no more then a syntatic sugar for getAttributeName() and setAttributeName(). Personally, i don't like to use attribute because it is hardly to understand than a simply get/set method.
CORBA also has valuetypes, object by value structure - better explaned here. They are very usefull because, different from struct, allow us inherit from other valuetypes, abstract interface or abstract valuetype. Usualy, when i'm modeling objects with alot of
get/set methods i prefer to use valuetypes instead of interfaces.
Going back to your question, the best way to understand 'attribute' is looking for C#. IIOP.NET maps 'attribute' to properties. A property simulates a public member but they are a get/set method.
Answering your question, i can't know if someObj.someName != someObj.someName will return true or false without see the someObj implementation. I will add two examples to give an ideia about what we can see.
Example 1) This implementation will always return false for the expression above:
private static i;
public string getSomeName() {
return "myName" i;
}
Example 2) This implementation bellow can return true or false, depending of concurrency or 'race condition' between clients.
public string getSomeName() {
return this.someName;
}
public setSomeName(string name) {
this.someName = name;
}
First client can try to access someObj.someName() != someObj.someName(). A second client could call setSomeName() before de second call from the first client.
It is perfectly acceptable for someObj.someName != someObj.someName to be true, oddly as it may seem.
The reason (as others alluded to) is because attributes map to real RPC functions. In the case of readonly attributes they just map to a setter, and for non-readonly attributes there's a setter and a getter implicitly created for you when the IDL gets compiled. But the important thing to know is that an IDL attribute has a dynamic, server-dictated, RPC-driven value.
IDL specifies a contract for distributed interactions which can be made at runtime between independent, decoupled entities. Almost every interaction with an IDL-based type will lead to an RPC call and any return value will be dependent on what the server decides to return.
If the attribute is, say, currentTime then you'll perhaps get the server's current clock time with each retrieval of the value. In this case, someObj.currentTime != someObj.currentTime will very likely always be true (assuming the time granularity used is smaller than the combined roundtrip time for two RPC calls).
If the attribute is instead currentBankBalance then you can still have someObj.currentBankBalance != someObj.currentBankBalance be true, because there may be other clients running elsewhere who are constantly modifying the attribute via the setter function, so you're dealing with a race condition too.
All that being said, if you take a very formal look at the IDL spec, it contains no language that actually requires that the setting/accessing of an attribute should result in an RPC call to the server. It could be served by the client-side ORB. In fact, that's something which some ORB vendors took advantage of back in the CORBA heyday. I used to work on the Orbix ORB, and we had a feature called Smart Proxies - something which would allow an application developer to overload the ORB-provided default client proxies (which would always forward all attribute calls to the server hosting the target object) with custom functionality (say, to cache the attribute values and return a local copy without incurring network or server overhead).
In summary, you need to be very clear and precise about what you are trying to verify formally. Given the dynamic and non-deterministic nature of the values they can return (and the fact that client ORBs might behave differently from each other and still remain compliant to the CORBA spec) you can only reliably expect IDL attributes to map to getters and setters that can be used to retrieve or set a value. There is simply no predictability surrounding the actual values returned.
Generally, attribute does not need to be backed by any data member on the server, although some language mapping might impose such convention.
So in general case it could happen that someObj.someName != someObj.someName. For instance attribute might be last access time.

ViewBag vs ViewData performance difference in MVC?

I know that ViewData and ViewBag both use the same backing data and that neither are as good as using strongly typed models in most cases. However when choosing between the two is the dynamic nature of ViewBag slower than using ViewData?
Okay - my initial answer basically said 'no' - time for a bit of a u-turn.
It should be 'no' in a perfect dynamic world - but upon closer inspection it would appear that there will either be no difference (accounting for JIT magic) or it might be ever-so-slightly slower, although not enough to warrant not using it (I certainly am).
In theory if properly implemented, the ViewBag would ultimately outperform the use of the ViewData dictionary because the binding of the expressions (e.g. ViewBag.Foo) is very well cached across the different CallSites that the compiler will generate (reflect a method that does a read or write to the ViewBag and you'll see what I mean).
The caching layers of the DLR are well documented (if a little difficult to understand once you get in depth) but basically the runtime does its best to 'remember' where a given value instance is once its bound it - for example via a Set or Get statement.
BUT The caching, its use and effectiveness, is entirely dependent upon the underlying implementations of classes/interfaces such as DynamicObject, IDynamicMetaObjectProvider etc; as well as the end-result of the Get/Set expression binding.
In the case of the MVC internal DynamicViewDataDictionary class - it ultimately ends up binding to this:
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this.ViewData[binder.Name];
return true;
}
For var a = ViewBag.Foo
And
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this.ViewData[binder.Name] = value;
return true;
}
For ViewBag.Foo = Bar;
In other words - the statements are effectively being rewritten to wrappers around the dictionary indexer.
Because of that, there's certainly no way it could be faster than doing it yourself.
Were ViewData to feed off of ViewBag, instead of the other way around, and had ViewBag then been implemented with even something like ExpandoObject, then it might be a different story - as the dynamic implementation of ExpandoObject is much more intelligent and the caching rules it employs allow for some pretty cool runtime optimisations.
In Conclusion
(thanks to Shawn McLean for suggesting one was needed!)
ViewBag will be slower than ViewData; but probably not enough to warrant concern.
I haven't done any test but my gut feel is that in real world scenarios the difference is just negligible. You will probably access it a few times on each page and a few CPU cycles won't make any difference. One can find bigger performance improvements in other places.

Do Delphi generic collections override equals?

This is a question for the generic collection gurus.
I'm shocked to find that TList does not override equals. Take a look at this example:
list1:=TList<String>.Create;
list2:=TList<String>.Create;
list1.Add('Test');
list2.Add('Test');
Result:=list1.Equals(list2);
"Result" is false, even though the two Lists contain the same data. It is using the default equals() (which just compares the two references for equality).
Looking at the code, it looks like the same is true for all the other generic collection types too.
Is this right, or am I missing something??
It seems like a big problem if trying to use TLists in practice. How do I get around this? Do I create my own TBetterList that extends TList and overrides equals to do something useful?
Or will I run into further complications with Delphi generics...... ?
[edit: I have one answer so far, with a lot of upvotes, but it doesn't really tell me what I want to know. I'll try to rephrase the question]
In Java, I can do this:
List<Person> list1=new ArrayList<Person>();
List<Person> list2=new ArrayList<Person>();
list1.add(person1);
list2.add(person1);
boolean result=list1.equals(list2);
result will be true. I don't have to subclass anything, it just works.
How can I do the equivalent in Delphi?
If I write the same code in Delphi, result will end up false.
If there is a solution that only works with TObjects but not Strings or Integers then that would be very useful too.
Generics aren't directly relevant to the crux of this question: The choice of what constitutes a valid base implementation of an Equals() test is entirely arbitrary. The current implementation of TList.Equals() is at least consistent will (I think) all other similar base classes in the VCL, and by similar I don't just mean collection or generic classes.
For example, TPersistent.Equals() also does a simple reference comparison - it does not compare values of any published properties, which would arguably be the semantic equivalent of the type of equality test you have in mind for TList.
You talk about extending TBetterList and doing something useful in the derived class as if it is a burdensome obligation placed on you, but that is the very essence of Object Oriented software development.
The base classes in the core framework provide things that are by definition of general utility. What you consider to be a valid implementation for Equals() may differ significantly from someone else's needs (or indeed within your own projects from one class derived from that base class to another).
So yes, it is then up to you to implement an extension to the provided base class that will in turn provide a new base class that is useful to you specifically.
But this is not a problem.
It is an opportunity.
:)
You will assuredly run into further problems with generics however, and not just in Delphi. ;)
What it boils down to is this:
In Java (and .NET languages) all types descend from Object. In Delphi integers, strings, etc. do not descend from TObject. They are native types and have no class definition.
The implications of this difference are sometimes subtle. In the case of generic collections Java has the luxury of assuming that any type will have a Equals method. So writing the default implementation of Equals is a simple matter of iterating through both lists and calling the Equals method on each object.
From AbstractList definition in Java 6 Open JDK:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator e2 = ((List) o).listIterator();
while(e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
As you can see the default implementation isn't really all that deep a comparison after all. You would still be overriding Equals for comparison of more complex objects.
In Delphi since the type of T cannot be guaranteed to be an object this default implementation of Equals just won't work. So Delphi's developers, having no alternative left overriding TObject.Equals to the application developer.
I looked around and found a solution in DeHL (an open source Delphi library). DeHL has a Collections library, with its own alternative List implementation. After asking the developer about this, the ability to compare generic TLists was added to the current unstable version of DeHL.
So this code will now give me the results I'm looking for (in Delphi):
list1:=TList<Person>.Create([Person.Create('Test')]);
list2:=TList<Person>.Create([Person.Create('Test')]);
PersonsEqual:=list1.Equals(list2); // equals true
It works for all types, including String and Integer types
stringList1:=TList<string>.Create(['Test']);
stringList2:=TList<string>.Create(['Test']);
StringsEqual:=stringList1.Equals(stringList2); // also equals true
Sweet!
You will need to check out the latest unstable version of DeHL (r497) to get this working. The current stable release (0.8.4) has the same behaviour as the standard Delphi TList.
Be warned, this is a recent change and may not make it into the final API of DeHL (I certainly hope it does).
So perhaps I will use DeHL instead of the standard Delphi collections? Which is a shame, as I prefer using standard platform libraries whenever I can. I will look further into DeHL.

Resources