How to set nested property with autofixture (it's readonly)? Something like this:
var result =
fixture.Build<X>()
.With(x => x.First.Second.Third, "value")
.Create();
If I understand the question correctly, I'll assume that we have classes like these:
public class X
{
public X(One first, string foo)
{
First = first;
Foo = foo;
}
public One First { get; }
public string Foo { get; }
}
public class One
{
public One(Two second, int bar)
{
Second = second;
Bar = bar;
}
public Two Second { get; }
public int Bar { get; }
}
public class Two
{
public Two(string third, bool baz)
{
Third = third;
Baz = baz;
}
public string Third { get; }
public bool Baz { get; }
}
Specifically, I've added the properties Foo, Bar, and Baz to each of those classes to emphasise that while one may be interested in setting x.First.Second.Third to a specific value, one would still be interested in having all other properties populated by AutoFixture.
As a general observation, once you start working with immutable values, this is where a language like C# starts to reveal its limitations. While possible, it goes against the grain of the language.
There's plenty of other advantages to writing code with immutable data, but it gets tedious in C#. That's one of the reasons I finally gave up on C# and moved on to F# and Haskell. While this is a bit of a digression, I mention this to explicitly communicate that I think that using read-only properties is a fine design decision, but that it comes with some known problems.
In general, when working with immutable values, particularly in testing, it's a good idea to add copy-and-update methods to each immutable class, starting with X:
public X WithFirst(One newFirst)
{
return new X(newFirst, this.Foo);
}
On One:
public One WithSecond(Two newSecond)
{
return new One(newSecond, this.Bar);
}
and on Two:
public Two WithThird(string newThird)
{
return new Two(newThird, this.Baz);
}
This enables you to use Fixture's Get extension method to produce an X value with a particular First.Second.Third value, but where all other values are populated freely by AutoFixture.
The following test passes:
[Fact]
public void BuildWithThird()
{
var fixture = new Fixture();
var actual =
fixture.Get((X x, One first, Two second) =>
x.WithFirst(first.WithSecond(second.WithThird("ploeh"))));
Assert.Equal("ploeh", actual.First.Second.Third);
Assert.NotNull(actual.Foo);
Assert.NotEqual(default(int), actual.First.Bar);
Assert.NotEqual(default(bool), actual.First.Second.Baz);
}
This uses an overload to Fixture.Get that takes a delegate with three input values. All those values are populated by AutoFixture, and you can then nest the copy-and-update methods using x, first, and second.
The assertions show that not only does actual.First.Second.Third have the expected value, but all other properties are populated as well.
Lenses
You may think that it seems redundant that you have to ask AutoFixture for the first and second values, since x should already contain those. Instead, you may want to be able to just 'reach into' First.Second.Third without having to deal with all of those intermediary values.
This is possible using lenses.
A lens is a construct with the origin in category theory, and used in some programming languages (most notably Haskell). Functional programming is all about immutable values, but even with functional languages with first-class support for immutable data, deeply nested immutable records are awkward when you just need to update a single datum.
I don't intend to turn this answer into a lenses tutorial, so if you really want to understand what's going on, search for a lenses tutorial in your favourite functional programming language.
In short, though, you can define a lens in C# like this:
public class Lens<T, V>
{
public Lens(Func<T, V> getter, Func<V, T, T> setter)
{
Getter = getter;
Setter = setter;
}
internal Func<T, V> Getter { get; }
internal Func<V, T, T> Setter { get; }
}
A lens is a pair of functions. The Getter returns the value of a property, given a 'full' object. The Setter is a function that takes a value, and an old object, and returns a new object with the property changed to the value.
You can define a set of functions that operate on lenses:
public static class Lens
{
public static V Get<T, V>(this Lens<T, V> lens, T item)
{
return lens.Getter(item);
}
public static T Set<T, V>(this Lens<T, V> lens, T item, V value)
{
return lens.Setter(value, item);
}
public static Lens<T, V> Compose<T, U, V>(
this Lens<T, U> lens1,
Lens<U, V> lens2)
{
return new Lens<T, V>(
x => lens2.Get(lens1.Get(x)),
(v, x) => lens1.Set(x, lens2.Set(lens1.Get(x), v)));
}
}
Set and Get simply enables you to get the value of a property, or to set a property to a particular value. The interesting function here is Compose, which enables you to compose a lens from T to U with a lens from U to V.
This works best if you have static lenses defined for each class, for example for X:
public static Lens<X, One> FirstLens =
new Lens<X, One>(x => x.First, (f, x) => x.WithFirst(f));
One:
public static Lens<One, Two> SecondLens =
new Lens<One, Two>(o => o.Second, (s, o) => o.WithSecond(s));
Two:
public static Lens<Two, string> ThirdLens =
new Lens<Two, string>(t => t.Third, (s, t) => t.WithThird(s));
This is boilerplate code, but it's straightforward once you get the hang of it. Even in Haskell it's boilerplate, but it can be automated with Template Haskell.
This enables you to write the test using a composed lens:
[Fact]
public void BuildWithLenses()
{
var fixture = new Fixture();
var actual = fixture.Get((X x) =>
X.FirstLens.Compose(One.SecondLens).Compose(Two.ThirdLens).Set(x, "ploeh"));
Assert.Equal("ploeh", actual.First.Second.Third);
Assert.NotNull(actual.Foo);
Assert.NotEqual(default(int), actual.First.Bar);
Assert.NotEqual(default(bool), actual.First.Second.Baz);
}
You take X.FirstLens, which is a lens from X to One and first compose it with One.SecondLens, which is a lens from One to Two. The result so far is a lens from X to Two.
Since this is a Fluent Inteface, you can keep going and compose this lens with Two.ThirdLens, which is a lens from Two to string. The final, composed lens is a lens from X to string.
You can then use the Set extension method to set this lens on x to "ploeh". The assertions are the same as above, and the test still passes.
The lens composition looks verbose, but that's mainly an artefact of C# limited support for custom operators. In Haskell, a similar composition would literally look like first.second.third, where first, second, and third are lenses.
Related
Background:
I am building an editor extension for Unity (although this question is not strictly unity related). The user can select a binary operation from a dropdown and the operation is performed on the inputs, as seen in the diagram:
The code is taken from a tutorial, and uses an enum here in combination with a switch statement here to achieve the desired behavior.
This next image demonstrates the relationship between the code and the behavior in the graph UI:
Problem
Based on my prior experience programming in other languages, and my desire to allow for user-extensible operations that don't require users to edit a switch statement in the core code, I would LIKE the resulting code to look something like this (invalid) C# code:
... snip ...
// OperatorSelection.GetSelections() is automagically populated by inheritors of the GenericOperation class
// So it would represent a collection of types?
// so the confusion is primarily around what type this should be
public GenericOperations /* ?? */ MathOperations = GenericOperation.GetOperations();
// this gets assigned by the editor when the user clicks
// the dropdown, but I'm unclear on what the type should
// be since it can be one of several types
// from the MathOperations collection
public Operation /* ?? */ operation;
public override object GetValue(NodePort port)
{
float a = GetInputValue<float>("a", this.a);
float b = GetInputValue<float>("b", this.b);
result = 0f;
result = operation(a, b);
return result;
}
... snip ...
Reference Behavior
To be crystal clear about the kind of behavior I'm hoping to achieve, here is a reference implementation in Python.
class GenericOperation:
#classmethod
def get_operations(cls):
return cls.__subclasses__()
class AddOperation(GenericOperation):
def __call__(self, a, b):
return a + b
if __name__ == '__main__':
op = AddOperation()
res = op(1, 2)
print(res) # 3
print(GenericOperation.get_operations()) # {<class '__main__.AddOperation'>}
Specific Questions
So ultimately this boils down to three interrelated questions:
What sort of type do I assign to MathOperations so that it can hold a collection of the subtypes of GenericOperation?
How do I get the subtypes of GenericOperation?
What type do I assign operation, which can be one of several types?
Work So Far
I have been looking into generics and reflection from some of the following sources, but so far none seem to provide exactly the information I'm looking for.
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics
https://igoro.com/archive/fun-with-c-generics-down-casting-to-a-generic-type/
Using enum as generic type parameter in C#
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generics-and-reflection
Edit: I edited the comments in the C# psuedocode to reflect that the primary confusion boils down to what the types should be for MathOperations and operation, and to note that the editor itself selects the operation from the MathOperations when the user clicks on the dropdown. I also changed the question so that they can be answered factually.
Usually I'd say your question is quite broad and the use case very tricky and requires a lot of not so trivial steps to approach. But I see you also have put quite an effort in research and your question so I'll try to do the same (little Christmas Present) ;)
In general I think generics is not what you want to use here. Generics always require compile time constant parameters.
As I am only on the phone and don't know I can't give you a full solution right now but I hope I can bring you into the right track.
1. Common Interface or base class
I think the simplest thing would rather be a common interface such as e.g.
public interface ITwoFloatOperation
{
public float GetResult(float a, float b);
}
A common abstract base class would of course do as well. (You could even go for a certain attribute on methods)
And then have some implementations such as e.g.
public class Add : ITwoFloatOperation
{
public float GetResult(float a, float b) => a + b;
}
public class Multiply : ITwoFloatOperation
{
public float GetResult(float a, float b) => a * b;
}
public class Power : ITwoFloatOperation
{
public float GetResult(float a, float b) Mathf.Pow(a, b);
}
... etc
2. Find all implementations using Reflection
You can then use Reflection (you already were on the right track there) in order to automatically find all available implementations of that interface like e.g. this
using System.Reflection;
using System.Linq;
...
var type = typeof(ITwoFloatOperation);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
3. Store/Serialize a selected type in Unity
Now you have all the types ...
However, in order to really use these within Unity you will need an additional special class that is [Serializable] and can store a type e.g. like
[Serializable]
// See https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
public class SerializableType : ISerializationCallbackReceiver
{
private Type type;
[SerializeField] private string typeName;
public Type Type => type;
public void OnBeforeSerialize()
{
typeName = type != null ? type.AssemblyQualifiedName : "";
}
public void OnAfterDeserialize()
{
if(!string.NullOrWhiteSpace(typeName)) type = Type.GetType(typeName);
}
}
4. Interface type selection and drawing the drop-down
Then since you don't want to type the names manually you would need a special drawer for the drop down menu with the given types that implement your interface (you see we are connecting the dots).
I would probably use an attribute like e.g.
[AttributeUsage(AttributeTarget.Field)]
public ImplementsAttribute : PropertyAttribute
{
public Type baseType;
public ImplementsAttribute (Type type)
{
baseType = type;
}
}
You could then expose the field as e.g.
[Implements(typeof (ITwoFloatOperation))]
public SerializableType operationType;
and then have a custom drawer. This depends of course on your needs. Honestly my editor scripting knowledge is more based on MonoBehaviour etc so I just hope you can somehow translate this into your graph thingy.
Something like e.g.
[CustomPropertyDrawer(typeof(ImplementsAttribute))]
public class ImplementsDrawer : PropertyDrawer
{
// Return the underlying type of s serialized property
private static Type GetType(SerializedProperty property)
{
// A little bit hacky we first get the type of the object that has this field
var parentType = property.serializedObject.targetObject.GetType();
// And then once again we use reflection to get the field via it's name again
var fi = parentType.GetField(property.propertyPath);
return fi.FieldType;
}
private static Type[] FindTypes (Type baseType)
{
var type = typeof(ITwoFloatOperation);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
return types.OrderBy(t => t.AssemblyQualifiedName).ToArray();
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
label = EditorGUI.BeginProperty(position, label, property);
var implements = attribute as ImplementsAttribute;
if (GetType(property) != typeof (SerializableType))
{
EditorGUI.HelpBox(position, MessageType.Error, "Implements only works for SerializableType!");
return;
}
var typeNameProperty = property.FindPropertyRelative("typeName");
var options = FindTypes (implements.baseType);
var guiOptions = options.Select(o => o.AssemblyQualifiedName).ToArray();
var currentType = string.IsNullOrWhiteSpace(typeNameProperty.stringValue) ? null : Type.GetType(typeNameProperty.stringValue);
var currentIndex = options.FindIndex(o => o == curtentType);
var newIndex = EditorGUI.Popup(position, label.text, currentIndex, guiOptions);
var newTypeName = newIndex >= 0 ? options[newIndex] : "";
property.stringValue = newTypeName;
EditorGUI.EndProperty();
}
}
5. Using the type to create an instance
Once you somehow can store and get the desired type as a last step we want to use it ^^
Again the solution would be reflection and the Activator which allows us to create an instance of any given dynamic type using Activator.CreateInstance
so once you have the field you would e.g. do
var instance = (ITwoFloatOperation) Activator.CreateInstance(operationType.Type));
var result = instance.GetResult(floatA, floatB);
Once all this is setup an working correctly ( ^^ ) your "users"/developers can add new operations as simple as implementing your interface.
Alternative Approach - "Scriptable Behaviors"
Thinking about it further I think I have another - maybe a bit more simple approach.
This option is maybe not what you were targeting originally and is not a drop-down but we will rather simply use the already existing object selection popup for assets!
You could use something I like to call "Scriptable Behaviours" and have a base ScriptableObject like
public abstract class TwoFloatOperation : ScriptableObject
{
public abstract float GetResult(float a, float b);
}
And then multiple implementations (note: all these have to be in different files!)
[CreateAssetMenu (fileName = "Add", menuName = "TwoFloatOperations/Add")]
public class Add : TwoFloatOperation
{
public float GetResult(float a, float b) => a + b;
}
[CreateAssetMenu (fileName = "Multiply", menuName = "TwoFloatOperations/Multiply")]
public class Multiply : TwoFloatOperation
{
public float GetResult(float a, float b) => a * b;
}
[CreateAssetMenu (fileName = "Power", menuName = "TwoFloatOperations/Power"]
public class Power : TwoFloatOperation
{
public float GetResult(float a, float b) Mathf.Pow(a, b);
}
Then you create one instance of each vis the ProjectView -> Right Click -> Create -> TwoFloatOperations
Once you did this for each type you can simply expose a field of type
public TwoFloatOperation operation;
and let Unity do all the reflection work to find instances which implement this in the assets.
You can simply click on the little dot next to the object field and Unity will list you all available options and you can even use the search bar to find one by name.
Advantage:
No dirty, expensive and error prone reflection required
Basically all based on already built-in functionality of the editor -> less worries with serialization etc
Disadvantage:
This breaks a little with the actual concept behind ScriptableObject since usually there would be multiple instances with different settings, not only a single one
As you see your developers have to not only inherit a certain type but additionally add the CreateAssetMenu attribute and actually create an instance in order to be able to use it.
As said typing this on the phone but I hope this helps with your use case and gives you an idea of how I would approach this
I'm looking to create named functions: objects that act as Func, but also have a string field containing a human-interpreted name.
The natural approach would be to make a class NamedFunc<T0,T1> : Func<T0,T1> { string name; } but unfortunately Func is not a class. So I'm looking for a workaround.
The end goal is that I have a function which DoMethod(MyObject victim, Func<T,T> op) and inside DoMethod I would need an alphanumeric representation of op (for caching and compatibility reasons). Currently I use op.toString().hashCode().toString() but I'd like something more meaningful, so that I can actually see which file belongs to sum, square, etc. instead of just seeing 8202589252, 58809258520, etc.
For example, I want to pass to DoMethod something along the lines of NewFunc<double,double> square = new NewFunc<double,double>(x=>x*x , "square"); and then when calling DoMethod(victim, square) DoMethod would somehow be able to recover that this function's string is "square" instead of "Func<double,double> x => x * x". At the same time, I want people to be able to just use regular Func as an input as well (without overloading the method).
Is there any feasible way to do this? Or am I looking for something impossible?
Although as you said, you can't use inheritance since Func is not a class, you can still use composition:
public class NamedFunc<T, R> {
public string Name { get; }
public Func<T, R> Invoke { get; }
public NamedFunc(Func<T, R> function, string name) {
Name = name;
Invoke = function;
}
public static implicit operator Func<T, R>(NamedFunc<T, R> namedFunc)
=> namedFunc.Invoke;
}
And you will be able to do what you want:
NamedFunc<double,double> square = new NamedFunc<double,double>(x=>x*x , "square");
To get its name, simply do square.Name. To call it, simply do square.Invoke(someNumber).
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'm writing a Linked List program in C# because I want to test how I feel about the language and I'm running into some serious difficulty. I'm trying to implement a Map method that functions like a Haskell map function (code below for both). However, I'm getting the error messages:
main.cs(43,66): error CS0029: Cannot implicitly convert type `void' to `MainClass.LinkedList<U>'
main.cs(43,33): error CS1662: Cannot convert `lambda expression' to delegate type `System.Func<MainClass.LinkedList<U>>' because some of the return types in the block are not implicitly convertible to the delegate return type
The relevant code in question:
Ideal Haskell code:
map :: [a] -> (a -> b) -> [b]
map (x:[]) f = (f x) : []
map (x:xs) f = (f x) : (map xs f)
C# code:
public class LinkedList<T> where T: class
{
public T first;
public LinkedList<T> rest;
public LinkedList(T x) {this.first = x;}
public void Join(LinkedList<T> xs)
{
Do(this.rest, ()=>this.rest.Join(xs), ()=>Assign(ref this.rest, xs));
}
public LinkedList<U> Map<U>(Func<T, U> f) where U: class
{
return DoR(this.rest, ()=>new LinkedList<U>(f(this.first)).Join(this.rest.Map(f)), ()=>new LinkedList<U>(f(this.first)));
}
public static void Assign<T>(ref T a, T b)
{
a = b;
}
public static U DoR<T, U>(T x, Func<U> f, Func<U> g)
{
if (x!=null) {return f();}
else {return g();}
}
public static void Do<T>(T x, Action f, Action g)
{
if (x != null) {f();}
else {g();}
}
While Assign, DoR (short for Do and Return), and Do seem like they're "code smell", they're what I came up with for trying to not write
if (x != null) {f();}
else {g();}
type statements (I'm used to patternmatching). If anybody has any better ideas, I'd love to know them, but mostly I'm concerned with the highlighted problem.
Starting with your immediate problem: the basic issue here is that you're mixing and matching lambda expressions that have either void return type or an actual return type. This can be addressed by changing your Join() method so that it returns the list used to call Join():
public LinkedList<T> Join(LinkedList<T> xs)
{
Do(this.rest, () => this.rest.Join(xs), () => Assign(ref this.rest, xs));
return this;
}
An alternative way would be to have a statement body lambda in the Map<U>() method that saves the new list to a variable and then returns that. But that adds a lot more code than just changing the Join() method, so it seems less preferable.
That said, you seem to be abusing C# a bit here. Just as when writing code in a functional language, one should really make an effort to write real functional code, in the manner idiomatic to that language, so too should one make an effort when writing C# code to write real imperative code, in the manner idiomatic to C#.
Yes, C# has some functional-like features in it, but they don't generally have the same power as the features found in real functional languages, and they are intended to allow C# programmers to get the low-hanging fruit of functional styles of code without having to switch languages. One particular thing also to be aware of is that lambda expressions generate a lot more code than normal C# imperative code.
Sticking to more idiomatic C# code, the data structure you're implementing above can be written much more concisely, and in a manner that creates much more efficient code. That would look something like this:
class LinkedList<T>
{
public T first;
public LinkedList<T> rest;
public LinkedList(T x) { first = x; }
public void Join(LinkedList<T> xs)
{
if (rest != null) rest.Join(xs);
else rest = xs;
}
public LinkedList<U> Map<U>(Func<T, U> f) where U : class
{
LinkedList<U> result = new LinkedList<U>(f(first));
if (rest != null) result.Join(rest.Map(f));
return result;
}
}
(For what it's worth, I don't see the point of the generic type constraint on your Map<U>() method. Why restrict it like that?)
Now, all that said, it seems to me that if you do want a functional-style linked-list implementation in C#, it would make sense to make it an immutable list. I'm not familiar with Haskell, but from my limited use of functional languages generally, I have the impression that immutability is a common feature in functional language data types, if not enforced 100% (e.g. XSL). So if trying to reimplement functional language constructs in C#, why not follow that paradigm?
See, for example, Eric Lippert's answer in Efficient implementation of immutable (double) LinkedList. Or his excellent series of articles on immutability in C# (you can start here: Immutability in C# Part One: Kinds of Immutability), where you can get ideas for how to create various immutable collection types.
In browsing Stack Overflow for related posts, I found several that, while not directly applicable to your question, may still be of interest (I know I found them very interesting):
how can I create a truly immutable doubly linked list in C#?
Immutable or not immutable?
Doubly Linked List in a Purely Functional Programming Language
Why does the same algorithm work in Scala much slower than in C#? And how to make it faster?
Converting C# code to F# (if statement)
I like that last one mainly for the way that in both the presentation of the question itself and the replies (answers and comments) help illustrate well why it's so important to avoid trying to just transliterate from one language to another, and instead to really try to become familiar with the way a language is designed to be used, and how common data structures and algorithms are represented in a given language, idiomatically.
Addendum:
Inspired by Eric Lippert's rough draft of an immutable list type, I wrote a different version that includes the Join() method, as well as the ability to add elements at the front and end of the list:
abstract class ImmutableList<T> : IEnumerable<T>
{
public static readonly ImmutableList<T> Empty = new EmptyList();
public abstract IEnumerator<T> GetEnumerator();
public abstract ImmutableList<T> AddLast(T t);
public abstract ImmutableList<T> InsertFirst(T t);
public ImmutableList<T> Join(ImmutableList<T> tail)
{
return new List(this, tail);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
class EmptyList : ImmutableList<T>
{
public override ImmutableList<T> AddLast(T t)
{
return new LeafList(t);
}
public override IEnumerator<T> GetEnumerator()
{
yield break;
}
public override ImmutableList<T> InsertFirst(T t)
{
return AddLast(t);
}
}
abstract class NonEmptyList : ImmutableList<T>
{
public override ImmutableList<T> AddLast(T t)
{
return new List(this, new LeafList(t));
}
public override ImmutableList<T> InsertFirst(T t)
{
return new List(new LeafList(t), this);
}
}
class LeafList : NonEmptyList
{
private readonly T _value;
public LeafList(T t)
{
_value = t;
}
public override IEnumerator<T> GetEnumerator()
{
yield return _value;
}
}
class List : NonEmptyList
{
private readonly ImmutableList<T> _head;
private readonly ImmutableList<T> _tail;
public List(ImmutableList<T> head, ImmutableList<T> tail)
{
_head = head;
_tail = tail;
}
public override IEnumerator<T> GetEnumerator()
{
return _head.Concat(_tail).GetEnumerator();
}
}
}
The public API is a little different from Eric's. You enumerate it to access the elements. The implementation is different as well; using a binary tree was how I enabled the Join() method.
Note that with the interface IEnumerable<T> implemented, one way to implement the Map<U>() method is to not do it at all and instead just use the built-in Enumerable.Select():
ImmutableList<T> list = ...; // whatever your list is
Func<T, U> map = ...; // whatever your projection is
IEnumerable<U> mapped = list.Select(map);
As long as the map function is relatively inexpensive, that would work fine. Any time mapped is enumerated, it will re-enumerate list, applying the map function. The mapped enumeration remains immutable, because it's based on the immutable list object.
There are probably other ways to do it (for that matter, I know of at least one other), but the above is what made the most sense to be conceptually.
I've something along this lines:
public class Something
{
private IDictionary<object,Activity> fCases;
public IDictionary<object,Activity> Cases
{
get { return fCases; }
set { fCases = value; }
}
}
public sealed class Something<T> : Something
{
private IDictionary<T,Activity> fCases;
public override IDictionary<T,Activity> Cases
{
get { return fCases; }
set { fCases = value; }
}
}
Note: override is not accepted on this case
Due to heavy Reflection usage there are situations where I've to downcast from Something<T> to Something but, I guess because Cases property is hidden, I'm losing Cases data.
How can I circumvent this situation? I've tried to use where T:object but that isn't accepted also.
EDIT:
This is an example of why I need inheritance:
if (someVar is Something) {
if (someVar.GetType().IsGenericType)
{
// Construct AnotherObject<T> depending on the Something<T>'s generic argument
Type typeArg = someVar.GetType().GetGenericArguments()[0],
genericDefinition = typeof(AnotherObject<>),
typeToConstruct = genericDefinition.makeGenericType(typeArgs);
object newAnotherObject = Activator.CreateInstance(typeToConstruct);
// Pass Something 'Cases' property to AnotherObject<T>
constructedType.InvokeMember(
"Cases",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
null,
newActivity,
new Object[] { someVar.Cases });
}
}
But, because 'Cases' is hidden, it will be always null. Without inheritance I would have to write a BIG if-then-else with all the possible generic arguments. And, believe me, I do really have to use someVar is Something and Reflection to construct all this objects. This is a big generic API being converted to other big generic API and so they should not known each other and the conversion should be as transparent as possible.
You won't be able to override it like that, and for good reason.
Imagine:
Something x = new Something<string>();
Button key = new Button();
x.Cases[key] = new Activity();
If your override worked, that would be trying to store a Button reference as a key in Dictionary<string, Activity>. That would be a Bad Thing.
Perhaps inheritance isn't actually appropriate in this case? If you could explain more about what you're trying to achieve, that would help. Perhaps you don't really need the dictionary as a property? Maybe just a method to fetch by key?
This is flat-out not going to work because the IDictionary<TKey, TValue> interface is invariant. An IDictionary<object, Activity> cannot be treated as an IDictionary<T, Activity>.
What you could do, rather than exposing an entire IDictionary<T, Activity> in your derived class, is simply delegate the calls you want to expose, like this:
public class Something
{
protected IDictionary<object, Activity> Cases { get; set; }
}
public sealed class Something<T> : Something
{
public Activity GetCase(T key)
{
return Cases[key];
}
public void AddCase(T key, Activity case)
{
Cases.Add(key, case);
}
// etc. etc.
}
Alternatively, you could also define your own contravariant interface, something like:
interface IKeyedCollection<in TKey, TValue>
{
TValue this[TKey key] { get; set; }
void Add(TKey key, TValue value);
}
For the above interface, an IKeyedCollection<object, Activity> could act as an IKeyedCollection<T, Activity> because every T is an object.
If you attempt to expose incompatible types at the different levels you're going to keep running into problems because at the end of the day you'll end up having to maintain 2 separate objects (or 1 custom object with 2 interfaces it can't completely satisfy).
These types are incompatible because there are values which can be added to IDictionary<object, Activity> which cannot be added to every instantiation of IDictionary<T, Activity>. Imagine for instance T is instatiated as string and the developer uses a int key elsewhere via Something. This creates a real problem for Something<string> implementations.
The way I would approach this is to change the base type Something to not expose a concrete type but instead to expose the relevant APIs.
public abstract class Something {
public abstract IEnumerable<KeyValuePair> GetElements();
public abstract bool TryGetValue(object key, out Activity value);
}
This gives Something<T> the flexbility it needs to properly sub-class Something and be very expressive about the types it wants to expose
public sealed class Something<T> : Something {
private IDictionary<T,Activity> fCases;
public override IDictionary<T,Activity> Cases
{
get { return fCases; }
set { fCases = value; }
}
public override IEnumerable<KeyValuPair<object, Activity>> GetElements() {
foreach (var cur in fCases) {
yield return new KeyValuePair<object, Activity>(cur.Key, cur.Value);
}
}
public override bool TryGetValue(object key, out Activity activity) {
try {
T typedKey = (T)key;
return fCases.TryGetValue(typedKey, out activity);
} catch (InvalidCastException) {
activity = null;
return false;
}
}
}
}
During heavy reflection usage I also had the need to 'upcast' from generic types. I knew certain calls would be compatible, but I didn't know the types at compile time. If you look at it this way, it is not really 'upcasting' a generic type, but rather, allowing to use generics during reflection by generating the correct downcasts.
To this end I created a helper method to create delegates along the lines of Delegate.CreateDelegate, but allowing to create a less generic delegate. Downcasts are generated where necessary. I explain it in detail on my blog.
MethodInfo methodToCall = typeof( string ).GetMethod( "Compare" );
Func<object, object, int> unknownArgument
= DelegateHelper.CreateDowncastingDelegate<Func<object, object, int>>(
null, methodToCall );
unknownArgument( "test", "test" ); // Will return 0.
unknownArgument( "test", 1 ); // Will compile, but throw InvalidCastException.
A bit later I had a need to create entire less generic wrapper classes for generic classes, so that all method calls would immediately become available as less generic calls during reflection. This might or might not be useful in your scenario as well. For this purpose I created a (not as thoroughly tested) method which allows to generate this wrapper class at runtime using emit. It is available in my open source library. I haven't written about this yet, so when interested you'll just have to try it out (and possibly see it fail since it's still quite new).