How do I convert
public class MyCustomList: List<MyCustomList>
back to MyCustomList after ordering?
myCustomListObject = myCustomListObject.OrderBy(...);
I tried .ToList() as myCustomListObject which returns null. What should I do?
public class MyCustomList: List<MyCustomList>
{
//stuff you already have here, including your current constructors
public MyCustomList(IEnumerable<MyCustomList> source)
{
//something here that (perhaps after using `this` to call
//one of the existing constructors, loads all of the items
//in source into it. There may be optimisations available
//in particular cases, as a bonus.
}
}
If you really want to be able to do something like the ToList() style, then you can add:
public static class MyBigOClassOHelpfulStaticMethods //maybe pick a better name
{
public static MyCustomList ToMyCustomList(this IEnumerable<MyCustomList> source)
{
return new MyCustomList(source);
}
}
Which isn't far off how ToList() works.
All this said though, if you are going to be often writing over the first MyCustomList with the new one, then there'd be something to gain by calling Sort instead of OrderBy, as Sort will sort the list in-place.
The problem is that ToList() will return a List. You cannot convert it to a MyCustomList just like you cannot convert another object some somthing that it isnt.
List<string> result = myCustomListObject.OrderBy(...).ToList();
If you really need a MyCustomListObject you should create a constructor that accepts a explicit cast operation.
If MyCustomList is just another name for List<string> you could use:
using MyCustomList = List<string>;
Then it will work like you want it to.
The return value of OrderBy simply is no instance of MyCustomList, and neither is the return value of ToList. Therefore, you cannot cast it to MyCustomList.
The only options you have are:
You create a new instance of MyCustomList and add the elements returned by OrderBy.
You replace the current contentes of your MyCustomList instance with the elements returned by OrderBy.
Without knowing more about your MyCustomList class, it is impossible to tell more. As it inherits from List<MyCustomList>, however, it can be assumed that both of the above options are feasible.
I agree with O. R. Mapper in that, without knowing more about MyCustomList, it's hard to answer. But you could just do something simple like this (again, without knowing more, this may now work):
void Main()
{
var list = new MyList() { new Stuff() { ugg = "z" }, new Stuff() { ugg = "b" } };
var myOrderedList = list.OrderBy(s => s.ugg);
myOrderedList.ToList().Dump();
var list2 = new MyList();
list2.AddRange(myOrderedList);
list2.GetType().Name.Dump();
}
public class Stuff{
public string ugg {get;set;}
}
// Define other methods and classes here
public class MyList : List<Stuff>{
}
I use LinqPad to display the contents and type names using the Dump() extension method.
Related
List<SomeClass> classObject = new List<SomeClass>();
someClass = .....
classObject.Add(someClass);
// For some reason we need to cast this List to List<object>.
List<object> objectList = classObject.Cast<object>().ToList();
// The receiving end will try then cast the item using the items in the objectList
var newInstance = Assembly.GetExecutingAssembly().CreateInstance(objectList[index].GetType().FullName);
All works except if the list is empty, the receiving ends are unable to cast new instance without knowing the fullname of the intended instance.
Is there anyway around it without passing the Type of someClass?
I have tried GetGenericArguments but failed as it returns System.Object which we can't use.
First of all a warning that I consider this a "hacky" solution, however you ask for a way so here it is.
The problem is that a List<object> doesn't hold the information we need. If there are items in the list you can work around this by checking the item, but this obviously doesn't work if there are no items in the list.
So we need to create a way to add the information we need to the List<object> we can do that by creating our own List<object>:
public class MyTypedObjectList : List<object>
{
public MyTypedObjectList(Type type)
{
MyType = type;
}
public Type MyType { get; }
}
And for ease of use we can create an extension method to do the creation for us:
public static class EnumerableExtensions
{
public static MyTypedObjectList ToMyTypedObjectList<T>(this IEnumerable<T> source)
{
var myTypedObjectList = new MyTypedObjectList(typeof(T));
myTypedObjectList.AddRange(source.Cast<object>());
return myTypedObjectList;
}
}
Now we can do:
List<object> objectList = classObject.ToMyTypedObjectList();
And use it as a List<object> all through the rest of the code.
Then in the receiving end (since we're using the same instance) we can cast back and get the type even if the list is empty:
var myTypedObjectList = (MyTypedObjectList) objectList;
And finally do this:
Assembly.GetExecutingAssembly().CreateInstance(myTypedObjectList.MyType.FullName);
As said this is a hacky way, but if you really wanted to this should solve your problem (but please consider refactoring and solving this the right way)
I wish in my class to return a list from a dictionary but allow custom sorting using pre-written comparison methods. In my original java code that I'm converting from, I created compare methods using Google Guava Ordering in my class and then had a single method called the following passing in one of the public comparator methods, kind of declared like this:
public List<Word> getWords(Comparator c) { }
I'm trying to recreate this in C# but I can't figure out how. Essentially in the code below you can see there are three versions for each type of sort, and in addition I end up creating two lists for every return value which seems a bit wasteful.
I looked at creating delegates but got a bit lost, then figured I could create an IComparable, but then saw IComparator and then saw Sort method takes a Comparator.
Can somebody point me in the direction of converting this into a single sort 'GetWords' in the best way, allowing clients to call the GetWords retrieving a sorted list from a pre-supplied set of ordering.
public partial class WordTable
{
private Dictionary<string, Word> words;
public WordTable()
{
//for testing
words = new Dictionary<string, Word>();
words.Add("B", new Word("B", WordTypes.Adjective));
words.Add("A", new Word("A", WordTypes.Noun));
words.Add("D", new Word("D", WordTypes.Verb));
}
public List<Word> GetWords()
{
return words.Values.ToList();
}
public List<Word> GetWordsByName()
{
List<Word> list = words.Values.ToList<Word>();
return list.OrderBy(word => word.Name).ToList();
}
public List<Word> GetWordsByType()
{
List<Word> list = words.Values.ToList<Word>();
return list.OrderBy(word => word.Type).ToList();
}
}
I think you are looking for predicates.
Effectively, you want a predefined set of predicates (one for ByName, one for ByType), and you pass this predicate into the GetWords function.
There are two approaches you can use.
IComparer
This is more closely related to your past Java experience.
The official way is to use IComparer<T> (link).
Similar to your Comparator in the Java example, this enables you to create different sorting methods which all implement the IComparer<Word> interface, and then you can dynamically choose your sorting method.
As a simple example:
public class WordNameComparer : IComparer<Word>
{
public int Compare(Word word1, Word word2)
{
return word1.Name.CompareTo(word2.Name);
}
}
And then you can do:
public List<Word> GetWords(IComparer<Word> comparer)
{
return words.Values.OrderBy(x => x, comparer).ToList();
}
Which you can call by doing:
var table = new WordTable();
List<Word> sortedWords = table.GetWords(new WordNameComparer());
And of course you change the sorting logic by passing a different IComparer<Word>.
Func parameters
From experience, this is a much preferred approach due to LINQ's enhanced readability and low implementation cost.
Looking at your last two methods, you should see that the only variable part is the lambda method that you use to order the data. You can of course turn this variably into a method parameter:
public List<Word> GetWordsBy<T>(Func<Word,T> orderByPredicate)
{
return words.Values.OrderBy(orderBy).ToList();
}
Because the OrderBy predicate uses a generic parameter for the selected property (e.g. sorting on a string field? an int field? ...), you have to make this method generic, but you don't need to explicitly use the generic parameter when you call the method. For example:
var sortedWordsByName = table.GetWordsBy(w => w.Name);
var sortedWordsByLength = table.GetWordsBy(w => w.Name.Length);
var sortedWordsByType = table.GetWordsBy(w => w.Type);
Note that if you select a class, not a value type, that you will either still have to create and pass an IComparer<> for this class, or the class itself must implement IComparable<> so it can be sorted the way you want it to be.
You can introduce ascending/descending ordering:
public List<Word> GetWordsBy<T>(Func<Word,T> orderByPredicate, bool sortAscending = true)
{
return sortAscending
? words.Values.OrderBy(orderBy).ToList()
? words.Values.OrderByDescending(orderBy).ToList();
}
Update
I was trying to do it with delegates, but avoiding the caller having to roll their own lambda statement and use predefined ones.
You can simply wrap your method with some predefined options:
public List<Word> GetWordsBy<T>(Func<Word,T> orderByPredicate)
{
return words.Values.OrderBy(orderBy).ToList();
}
public List<Word> GetWordsByName()
{
return GetWordsBy(w => w.Name);
}
This way, your external callers don't need to use the lambda if they don't want to; but you still retain the benefits of having reusable code inside your class.
There are many ways to do this. I prefer creating preset methods for readability's sake, but you could instead have an enum which you then map to the correct Func. Or you could create some static preset lambdas which the external caller can reference. Or... The world is your oyster :-)
I hope this works, or even compiles.
class WordTable
{
public List<Word> GetWords(IComparer<Word> comparer)
{
return words.Values.OrderBy(x => x, comparer).ToList();
}
}
class WordsByNameAndThenTypeComparer : IComparer<Word>
{
public override int Compare(Word x, Word y)
{
int byName = x.Name.CompareTo(y.Name);
return byName != 0 ? byName : x.Type.CompareTo(y.Type);
}
}
Usage:
WordTable wt = new WordTable();
List<Words> words = wt.GetWords(new WordsByNameAndThenTypeComparer());
I am adding some localization logic that I want to use application wide and instead of creating it multiple times I have decided to create a Generic method for this scenario and it works, but my Generics knowledge is limited, and it just doesn't feel optimal...
Method:
public List<T> Localize<T>(List<T> inputList, string propertyName)
{
var filteredList = new List<T>();
foreach (var item in inputList)
{
var clone = Mapper.Map<T, T>(item);
// "TranslationKey" is the fixed/same column name for every entity/table.
var translationKey = item.GetType().GetProperty("TranslationKey").GetValue(clone).ToString();
if (!string.IsNullOrEmpty(translationKey))
{
var prop = clone.GetType().GetProperty(propertyName);
prop.SetValue(clone, TranslateAsync(translationKey).Result);
}
filteredList.Add(clone);
}
return filteredList;
}
Then I would call the method like so:
var items = Localize(itemsList, "Description"); // To localize "Description" prop
var people = Localize(peopleList, "Name"); // To localize "Name" prop of People list...
So my two main questions are:
Can I optimize my methods implementation?
Is there a way I could not hard code property names when calling the method or is there a better/faster LINQ way or something I am missing?
Since reflection is used for getters/setters, which can probably be avoided, there is indeed room for optimization and more importantly making the code safer in case objects are changed in the future.
The first reflection item.GetType().GetProperty("TranslationKey").GetValue(clone) implies that type T always has a property TranslationKey. The generic constraints can enforce that, as long as all objects implement the proper interface (or share the same base class)
For example, the Item class and People class both implement something like interface ITranslationEntity{string TranslationKey{get;}} and if the method signature contains where T:ITranslationEntity, the property can be accessed directly
The setter could be done with the same interface implementation, e.g. have a SetTranslatedValue(string) on the interface, or the setter can be implemented as a lambda public List<T> Localize<T>(List<T> inputList, Action<T,string> setter) Used the latter as an example here, but having it in the interface would personally seem the better choice.
A small extra change which could make the call easier, but depends on whether you can place this method in a static class, is to make the method an extension method.
Perhaps the most important part is that the async call is executed synchronously in the loop (by accessing the Result ). Perhaps the implementation isn't truly asynchronous, but if it is, the major optimization is to combine the async calls and await the set of Tasks (and set the result inside a ContinueWith
End result:
static class SomeClass
{
public static List<T> Localize<T>(this List<T> inputList, Action<T,string> setter)
where T:ITranslationEntity
{
var clonedList = inputList.Select(Mapper.Map<T,T>).ToList();
var tasks = (from clone in clonedList
let key = clone.TranslationKey
where key != null
select TranslateAsync(key).ContinueWith(t=> setter(clone,t.Result))).ToArray();
Task.WaitAll(tasks);
return clonedList;
}
}
Example call:
var items = itemsList.Localize((i,val) =>i.Description = val);
Again, the setter is just an alternative and implementing that in other ways might be better, but the major point is to avoid reflection whenever possible and if async code is called for multiple items, to await the result of the combined tasks.
Can I optimize my methods implementation?
Well, that depends on what you mean by "optimize". I think you can convert your foreach loop into a LINQ Select call followed by a Where call to filter out the nulls.
Is there a way I could not hard code property names when calling the method or is there a better/faster LINQ way or something I am missing?
I suggest using the nameof operator when you pass the property name, so instead of this:
var items = Localize(itemsList, "Description");
You can do this:
var items = Localize(itemsList, nameof(Description));
This way, you can avoid hard coding the strings!
Firstly, using reflection to reset some property is far from being optimized. You probably need to refactor to some kind of Visitor so eventually your code will look like:
new EnglishVisitor.Visit(myObject);
As I see, your classes are responsible for providing some sort of TrnslationKey, right? So next step is to extract appropriate interface:
publuc interface ITranslationKeyProvider { string GetTranslationKey(); }
...and this gives you an opportunity to make it more safe with helps of generics:
public T Visit<T>(T object) where T : ITranslationKeyProvider
so the compiler won't let you to pass something completely different.
It will be much much much more better if you use dynamic keyword to defer type-check up to runtime moment.
Regarding your generics. Thet are perfectly fine.
It seems from your design that TranslationKey can be used to localize exactly one property for each entity, so the following does not make sense:
Localize(itemsList, "Description");
Localize(itemsList, "Title"); // cannot do that, because only description is localizable
If that is the case - you don't need to specify property to localize when calling the method. Instead, use interface like this:
public interface ITranslatable {
string TranslationKey { get; }
string TranslatedProperty { get; set; }
}
class MyEntity : ITranslatable {
public string TranslationKey { get; set; }
public string Description { get; set; }
// implicit implementation to avoid clutter
string ITranslatable.TranslatedProperty
{
get { return Description; }
set { Description = value; }
}
}
And your Localize method does not need any reflection any more:
public static List<T> Localize<T>(List<T> inputList) where T:ITranslatable
{
var filteredList = new List<T>();
foreach (var item in inputList) {
var clone = Mapper.Map<T, T>(item);
// "TranslationKey" is the fixed/same column name for every entity/table.
if (!string.IsNullOrEmpty(clone.TranslationKey))
clone.TranslatedProperty = TranslateAsync(clone.TranslationKey).Result;
filteredList.Add(clone);
}
return filteredList;
}
There are several points you could address:
1. TranslationKey property
When using something like item.GetType().GetProperty("TranslationKey").GetValue(clone) in a generic method, that means the type is always constained to have a TranslationKey property. I would suggest to use some interface and generic constraint for improving both speed and add a compile-time checks. For example:
public interface ITranslatable
{
string TranslationKey { get; }
}
usage:
public void Translate<T>(T value) where T : ITranslatable
{
var translationKey = value.TranslationKey;
...
}
This might not be possible to achieve though, especially when using 3rd party types.
2. Retrieving PropertyInfo in each iteration
Your code seems to be always accessing the same property for each element of the collection passed in:
foreach (var item in items)
{
var clone = Mapper.Map<T, T>();
...
var prop = clone.GetType().GetProperty(propertyName);
...
}
You can simply load the property only once for each method call outside of the foreach, this will save some time on the reflection (especially on big collections). If you wanted to optimize for speed further, you could also cache the properties for given type, but I wouldn't recommend it as a starter.
This may not be valid if Mapper.Map<T, T> can actually take and return a type that is more derived than T and hides the propertyName property (e.g. via new keyword).
3. List size
Additional minor point is that you allocate the filteredList without any size hint, yet the size is known, it is the size of inputList. This can save some time on big collections. In addition, the type of inputList parameter can be IReadOnlyCollection, improving the signature to reflect what is being done with it.
LINQ
I would oppose against LINQ usage here because of the prop.SetValue(clone, TranslateAsync(translationKey).Result); side-effect in your foreach loop. You could still return IReadOnlyCollection or IReadOnlyList from the method though, leading to a better flow on usage places.
Final code
public IReadOnlyCollection<T> Localize<T>(IReadOnlyCollection<T> inputList, string propertyName) where T : ITranslatable
{
var prop = typeof(T).GetProperty(propertyName);
var filteredList = new List<T>(inputList.Count);
foreach (var item in inputList)
{
var clone = Mapper.Map<T, T>(item);
// "TranslationKey" is the fixed/same column name for every entity/table.
var translationKey = clone.TranslationKey;
if (!string.IsNullOrEmpty(translationKey))
{
prop.SetValue(clone, TranslateAsync(translationKey).Result);
}
filteredList.Add(clone);
}
return filteredList;
}
Adding this answer (arrived from other answers) as yet another alternative for future, this way I can expose Localize to Singular and Multiple objects:
public List<T> Localize<T>(List<T> inputList, Action<T, string> setter) where T : ITranslatable
{
return inputList.Select(a => Localize(a, setter)).ToList();
}
public T Localize<T>(T input, Action<T, string> setter) where T : ITranslatable
{
var clone = Mapper.Map<T, T>(input);
var translationKey = clone.TranslationKey;
if (!string.IsNullOrEmpty(translationKey))
{
setter(clone, TranslateAsync(translationKey).Result);
}
return clone;
}
Interface:
public interface ITranslatable
{
string TranslationKey{ get; }
}
Call like this:
Localize(items, (i, val) => i.Description= val); // etc.
This issue has been bugging me for a while. Abstractly speaking, regardless of language, there are often situations when you want to have a method like this:
Collection method(Collection c) {
// select some elements from c based on some filter
// and return a new collection
}
Now, Collection is in this case some abstract class (Like say IList in C# or List in Java) with several implementations. I've been wondering what exactly is the right procedure to produce the abstract collection?
Is it ok to create a concrete collection inside the method and return it? Like:
Collection method(Collection c) {
Collection cc = new ConcreteCollection();
// select some elements from c based on some filter
return cc;
}
This of course puts a constraint on the resulting collection and will produce problems in case, for some reason, we want to cast the result of the method to a different concrete collection than the one used inside the method.
Or, use reflection to determine the actual concrete type of c and create an instance of that class:
Collection method(Collection c) {
Collection cc = c.getClass().newInstance();
// select some elements from c based on some filter
return cc;
}
For some reason this does not seem very "elegant" to me. I would greatly appreciate some insight in this matter.
(Speaking for java). The reason you're returning Collection (an interface) rather than a concrete type (such as ArrayList) is that you're telling the user that they shouldn't care about what the actual concrete type being used is. This leaves you free to choose the appropriate type for your library/api.
If you're enforcing a particular concrete class, then you should be returning that concrete class, rather than the interface.
So, they shouldn't be casting your return type to anything else other than Collection. See
When should I return the Interface and when the concrete class?.
In Java, there are actually some good examples of how to do this in the java.util.Collections class. Instead of taking a Collection and returning a Collection, the key methods take two collections, the "src" and the "dest". For example, Look at the signature of the copy method:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
This puts the responsibility of instantiating the destination list on the caller.
I think you could do the same thing when you want to create a method that acts on a src Collection and puts the results into a destination Collection (rather than Lists).
I agree with Matthew Farwell's answer that you probably just want to return the interface and utilize that, but for the times when you really do need to work with a specific implementing class you can do it the same way the Collections class does it.
One approach you could take is to create a Collection implementation that delegates calls through to the original Collection. This defers the potentially expensive operation of filtering a large Collection until you need to explicitly read elements. It also saves memory.
Example
public interface Filter<T> {
boolean include(T t);
}
public class FilterCollection<T> implements Collection<T> {
private final Collection<T> orig;
private final Filter<T> filter;
public FilterCollection(Collection<T> orig, Filter<T> filter) {
this.orig = orig;
this.filter = filter;
}
public int size() {
int sz = 0;
for (T t : orig) {
if (filter.include(t)) {
++sz;
}
}
return sz;
}
public boolean contains(Object o) {
return o instanceof T && filter.include((T) o) && orig.contains(o);
}
public boolean add(T t) {
if (!filter.include(t)) {
throw new IllegalArgumentException("Element lies outside filter bounds.");
}
orig.add(t);
}
}
The caller should assume a given type of Collection is returned.
Instead it should either copy to the desired type or pass the desired type.
e.g.
Set<T> set2 = new HashSet<T>(filter(set));
List<T> list2 = new ArrayList<T>(filter(list));
or
filter(set2, set); // the target collection is passed.
filter(list2, list);
To the question about ConcreteCollection, it is definitely allowable.
To the concern about having a different concrete collection expected, there are a few ways to go around the problem:
Change the return type of the method. Example:
ConcreteCollection method(Collection c){
ConcreteCollection cc=new ConcreteCollection
for(Object x: c){
//do something
}
return cc
}
Make use of polymorphism. Example:
Collection x=method(c)
x.add(new Object) //add is a method defined within the abstract Collection
Use some utilities to cast the type. Example:
LinkedList h=Collections.toLinkedList(method(c))
Hoped my answer helped. ^^
As far as I can understand, you want to know how to make a method that accepts generic list and returns another modified generic list.
So, my advice will be to use an abstract type that implements method to modify its state.
IList<object> list = new List<object>();
list.Add(new object());
list.Remove(obj);
Or as showed above, instantiate a list that implements IList (or the Java equivalent) work with this instance and return the result as a IList
Edit
If you want to filter some item from a list to a new one, generics can help (I don't know if this feature exists in Java).
public IList<T> Filter<T>(IList<T> list)
{
var result = new List<T>();
result.Add(list[0]); // Or whatever filtering method
return result;
}
If you want your method to accept as many different collection types as possible, and you want to be sure that the result is the same implementation type as what you put in, you might want to use a void method which directly modifies the supplied collection. For instance:
import com.google.common.base.Predicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Testy {
private static <T> void filter(Iterable<T> collection, Predicate<T> filter) {
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
if (!filter.apply(iterator.next())) { // Condition goes here
iterator.remove();
}
}
}
public static void main(String... args) {
List<String> list = new ArrayList<String>();
list.addAll(Arrays.asList("A", "B", "C", "D"));
filter(list, new Predicate<String>() { // Anonymous filter (predicate)
#Override public boolean apply(String input) {
return input.equals("B");
}
});
System.out.println(list); // Prints ["B"]
}
}
The helper method filter takes an Iterable, the simplest type required for iterating over something. Apply the filter to each element, and if the predicate (filter) returns false, remove that element from the underlying collection with Iterator.remove().
The Predicate<T> interface here comes from Google. You can easily write your own if you don't wish to import it. The only required method is apply(T) which returns a boolean. Either that, or just write your condition directly inside the loop and get rid of the second parameter.
This method is the most efficient if your original collection is mutable and you don't wish to keep any intermediate results.
Another option is to use Google Collections Collections2.filter(Collection<E>, Predicate<E>) which returns a Collection<E> just like in your question. Similarly, the Iterables class will do the same thing, but create lazy iterables where the filters are only applied when actually doing the iterating.
See comment in Main(). Why can't I perform the following?
public class SomeList<T> : List<T>
{
public SomeList(List<T> existing)
{
foreach (var item in existing)
Add(item);
}
public override string ToString()
{
return "I'm a better list.";
}
}
internal interface IReadStuff<T>
{
List<T> ReadStuff();
}
public class ReaderStrategy<Foo> : IReadStuff<Foo>
{
public List<Foo> ReadStuff()
{
return new List<Foo>();
}
}
public class Foo {}
public class Main
{
public Main()
{
var reader = new ReaderStrategy<Foo>();
// This works, but type is List<Foo>, not SomeList<Foo>
List<Foo> aList = reader.ReadStuff();
// This does not compile, but is what I want to do:
SomeList<Foo> aBetterList = reader.ReadStuff();
// This compiles, but always generates null for aBetterList:
SomeList<Foo> anotherBetterList = reader.ReadStuff() as SomeList<Foo>;
// This is funky but works:
SomeList<Foo> works = new SomeList<Foo>(reader.ReadStuff());
}
}
I am struggling understanding how to use generics with inherited types. I have a need for the above because I want to extend the functionality of List<T> is some special way, for example see SomeList<T> overrides ToString(). However, I want to keep my factory strategy using .Net generic List<T>. Is there a way to make this work?
Edit
I added a constructor that accepts List<T> and adds to SomeList<T>. This doesn't seem natural, but works. This is an expensive operation, especially if List<T> is large.
My question title was not the best, what I was striving for was an example showing a better way to do this.
reader.ReadStuff() returns List<Foo> - but you are trying to assign it to an object of type SomeList<Foo> which inherits from List<Foo>. This doesn't work because List<Foo> is not a SomeList<Foo> - it's the other way round.
Think about it - it is legal to return a List<Foo> object from ReadStuff() - then you are trying to access functionality on this object that is only available on SomeList<Foo> - this will break and that's why OOP doesn't allow you to do this - instances of a child class can be used where an instance of a parent class is expected - but you cannot use a parent class where a child class is expected.
Going back to your question title: SomeList<T> : List<T> can't be cast as List<T>? Yes that's possible, but you are trying to cast List<T> to SomeList<T>.
All instances of SomeList are instances of List. However, not all instances of List are instances of SomeList. That is what the second assignment is doing. reader.ReadStuff() returns a List, not a SomeList. Hope this helps.
In your example, you're not casting an instance of SomeList<Foo> to List<Foo>, you're trying to cast a List<Foo> to a SomeList<Foo>. You're going from less specific to more specific, which doesn't work. It should work the other way around.
change this code
SomeList<Foo> aBetterList = reader.ReadStuff()
to
SomeList<Foo> aBetterList = reader.ReadStuff() as SomeList<Foo>;
before using
if(aBetterList !=null) {}