Lazy property requiring "this" - c#

Here is an example of a property I have, coded as simply as possible
private IEnumerable<int> _blocks;
private bool _blocksEvaluated;
public IEnumerable<int> Blocks
{
get
{
if (!_blocksEvaluated)
{
_blocksEvaluated = true;
_blocks = this.CalculateBlocks(0).FirstOrDefault();
}
return _blocks;
}
}
This is verbose; I would like to make it more concise if possible. The following would be acceptable...
private Lazy<IEnumerable<int>> _blocks =
new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
... but it doesn't compile.
Keyword 'this' is not valid in a static property, static method, or static field initializer
So I came up with the following
struct MyLazy<TResult>
{
private bool evaluated;
private TResult result;
public TResult Evaluate(Func<TResult> func)
{
if (!evaluated)
{
evaluated = true;
result = func();
}
return result;
}
}
private MyLazy<IEnumerable<int>> _blocks;
public IEnumerable<int> Blocks
{
get { return _blocks.Evaluate(() => this.CalculateBlocks(0).FirstOrDefault()); }
}
Which I like best, but is there a better way?
Note - I realize that mutable structs are usually evil, but they seem really useful for this one particular problem.

Just initialize your field in the constructor.
public class MyClass
{
public MyClass()
{
_blocks = new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
}
private readonly Lazy<IEnumerable<int>> _blocks;
}

You can't use this when initializing an instance field, but you can simply initialize it in the constructor to address that.
private Lazy<IEnumerable<int>> _blocks;
public MyClass()
{
_blocks = new Lazy<IEnumerable<int>>(
() => this.CalculateBlocks(0).FirstOrDefault());
}
public IEnumerable<int> Blocks
{
get
{
return _blocks.Value;
}
}

Related

Delegates to generic operations where the generic type is unknown. How to create something like that?

Suppose I have the following code.
static class Store<T> {
public static T A;
public static T B;
public static T C;
}
public static class Store {
public static Value A = new Value(<T>(v) => Store<T>.A = v); //just an example of what I want
public static Value B = new Value(<T>(v) => Store<T>.B = v); //just an example of what I want
public static Value C = new Value(SetC<T>); //just an example of what I want
public static void SetA<T>(T value) { Store<T>.A = value; }
public static void SetB<T>(T value) { Store<T>.B = value; }
public static void SetC<T>(T value) { Store<T>.C = value; }
}
public class Value {
Action<T><T> _valueChanger; //just an example of what I want
public Value(Action<T><T> valueChanger) { //just an example of what I want
_valueChanger = valueChanger;
}
public void SetValue<T> (T value) {
_valueChanger<T>(value); //just an example of what I want
}
}
I want to write Store.A.SetValue(42) so that the value is saved to Store<int>.A. What can I write instead of the lines marked by "just an example of what I want" to make that happen? (I want to explore a solution that doesn't involve dictionaries or something similar)
Rephrasing the question:
I want to modify class Value (define some fields, write a constructor and write the method Value.SetValue(T value) ), then construct three different variables of type Value (A, B, C) in such a way that when I call Store.A.SetValue(42) the value Store<int>.A is changed to 42.
Another variation of the classes:
static class Holder<T> {
T Value { get; set; }
}
static class Store2<T> {
public static Holder<T> A = new Holder<T>();
public static Holder<T> B = new Holder<T>();
public static Holder<T> C = new Holder<T>();
}
public static class Store2 {
public static Value A = new Value2(Store2<>.A); //just an example of what I want
public static Value B = new Value2(Store2<>.B); //passing non-specific generic expression
public static Value C = new Value3({TFree}() => Store2<TFree>.C); //just an example of what I want
}
public class Value2 { //Non-generic class!
Holder{TFree}<TFree> _holder; //just an example of what I want
public Value(Holder{TFree}<TFree> holder) { //just an example of what I want
_holder = holder;
}
public void SetValue<T> (T value) {
_holder{T}.Value = value; //just an example of what I want
}
}
public class Value3 { //Non-generic class! (Another variation)
Func{TFree}<Holder<TFree>> _holderFactory; //just an example of what I want
public Value(Func{TFree}<Holder<TFree>> holderFactory) { //just an example of what I want
_holderFactory = holderFactory;
}
public void SetValue<T> (T value) {
Holder<T> holder = _holderFactory{T}(); //just an example of what I want
holder.Value = value;
}
}
Solution:
An easy reflection-free and collection-free solution was found using the answers to another question ( Emulating delegates with free generic type parameters in C# and Emulating delegates with free generic type parameters in C#). The solution is Delegates to generic operations where the generic type is unknown. How to create something like that?.
Use an array to store the values and access them through a property using an index
public static class Store<T>
{
public static readonly T[] Values = new T[3];
public static T A { get { return Values[0]; } set { Values[0] = value; } }
public static T B { get { return Values[1]; } set { Values[1] = value; } }
public static T C { get { return Values[2]; } set { Values[2] = value; } }
}
public static class Store
{
public static readonly Value A = new Value(0);
public static readonly Value B = new Value(1);
public static readonly Value C = new Value(2);
}
public class Value
{
private int _index;
public Value(int index)
{
_index = index;
}
public void SetValue<T>(T value)
{
Store<T>.Values[_index] = value;
}
public T GetValue<T>()
{
return Store<T>.Values[_index];
}
}
Since the constructor of Value is not aware of any generic type parameter, you cannot have any reference to a specific Store<T>.
UPDATE
Be aware of the fact that a copy of Store<T> will be created for every distinct type argument that you supplied for T. See this example
Store.A.SetValue(42);
Store.A.SetValue("Douglas Adams");
Store.A.SetValue(new DirectoryInfo(#"C:\"));
Store.A.SetValue(new List<int>());
var x1 = Store.A.GetValue<int>(); // --> 42
var x2 = Store.A.GetValue<string>(); // --> "Douglas Adams"
var x3 = Store.A.GetValue<DirectoryInfo>(); // --> DirectoryInfo{ C:\ }
var x4 = Store.A.GetValue<List<int>>(); // --> List<int>{ Count = 0 }
By using the debugger, you will see that four different values are stored in A at the same time! Of cause these are four differents A's that exist in four diffferent Store<T>.
The problem turned out to be solvable. Mike-z gave me a nearly right solution for the delegate-to-generic-method problem ( Emulating delegates with free generic type parameters in C#) which I modified to be a full solution: ( Emulating delegates with free generic type parameters in C#).
The solution this question becomes easy too. Interfaces can contain generic methods and we can use the interface-valued variables to store links to generic methods without specifying concrete type arguments. The following code utilizes the Store<T> class without modifications and uses the ISetter interface and ASetter/BSetter/CSetter "closures" to hold references to different generic members. The Value class stores the references in a ISetter-typed variable and uses the generic member which the _setter links to once the type argument T becomes available.
public interface ISetter {
void SetValue<T>(T value);
}
public static class Store {
public static Value A = new Value(new ASetter());
public static Value B = new Value(new BSetter());
public static Value C = new Value(new CSetter());
class ASetter : ISetter {
public void SetValue<T>(T value) { Store<T>.A = value; }
}
class BSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.B = value; }
}
class CSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.C = value; }
}
}
public class Value {
ISetter _setter;
public Value(ISetter setter) {
_setter = setter;
}
public void SetValue<T> (T value) {
_setter.SetValue<T>(value);
}
}

How to expose read-only collection another type of private collection?

Here is my problem: there is a class that contains a inner collection (or list, or array, or something like this) of some some class and It must expose a public read-only collection of items, which are properties (or fields) of relative items in inner collection. For example:
//Inner collection consists of items of this class
class SomeClass
{
public int _age;
//This property is needed for exposing
public string Age { get { return this._age.ToString(); } }
}
//Keeps inner collection and expose outer read-only collection
class AnotherClass
{
private List<SomeClass> _innerList = new List<SomeClass> ();
public ReadOnlyCollection<string> Ages
{
get
{
//How to implement what i need?
}
}
}
I know a simple way to do this by the use of a pair of inner lists, where the second keeps values of needed properties of first. Something like this:
//Inner collection consists of items of this class
class SomeClass
{
public int _age;
//This property is needed for exposing
public string Age { get { return this._age.ToString(); } }
}
//Keeps inner collection and expose outer read-only collection
class AnotherClass
{
private List<SomeClass> _innerList = new List<SomeClass> ();
private List<string> _innerAgesList = new List<string> ();
public ReadOnlyCollection<string> Ages
{
get
{
return this._innerAgesList.AsreadOnly();
}
}
}
But I dislike this overhead. May be there is some way to do what I want with exposing interfaces. Help me, please!
Hurra!
It seems that the best solution has been found. Due to the post of Groo
this problem found its almost universal answer. Here is It (we need to add two entity):
public interface IIndexable<T> : IEnumerable<T>
{
T this[int index] { get; }
int Count { get; }
}
class Indexer <Tsource, Ttarget> : IIndexable<Ttarget>
{
private IList<Tsource> _source = null;
private Func<Tsource, Ttarget> _func = null;
public Indexer(IList<Tsource> list, Func<Tsource, Ttarget> projection)
{
this._source = list;
this._func = projection;
}
public Ttarget this[int index] { get { return this._func(this._source[index]); } }
public int Count { get { return _source.Count; } }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public IEnumerator<Ttarget> GetEnumerator()
{ foreach (Tsource src in this._source) yield return this._func(src); }
}
With them, our implementation looks like this:
//Inner collection consists of items of this class
class SomeClass
{
public int _age;
//This property is needed for exposing
public string Age { get { return this._age.ToString(); } }
}
//Keeps inner collection and expose outer read-only collection
class AnotherClass
{
private List<SomeClass> _innerList = new List<SomeClass> ();
private Indexer<SomeClass, string> _indexer = null;
public AnotherClass ()
{ this._indexer = new Indexer<SomeClass, string > (this._innerList, s => s.Age); }
public IIndexable<string> Ages { get { return this._indexer; } }
}
Thank Groo and the rest who answered. Hope, this helps someone else.
The overhead is not so significant if you consider that ReadOnlyCollection is a wrapper around the list (i.e. it doesn't create a copy of all the items).
In other words, if your class looked like this:
class AnotherClass
{
private ReadOnlyCollection<string> _readonlyList;
public ReadOnlyCollection<string> ReadonlyList
{
get { return _readonlyList; }
}
private List<string> _list;
public List<string> List
{
get { return _list; }
}
public AnotherClass()
{
_list = new List<string>();
_readonlyList = new ReadOnlyCollection<string>(_list);
}
}
Then any change to the List property is reflected in the ReadOnlyList property:
class Program
{
static void Main(string[] args)
{
AnotherClass c = new AnotherClass();
c.List.Add("aaa");
Console.WriteLine(c.ReadonlyList[0]); // prints "aaa"
c.List.Add("bbb");
Console.WriteLine(c.ReadonlyList[1]); // prints "bbb"
Console.Read();
}
}
You may have issues with thread safety, but exposing IEnumerable is even worse for that matter.
Personally, I use a custom IIndexable<T> interface with several handy wrapper classes and extension method that I use all over my code for immutable lists. It allows random access to list elements, and does not expose any methods for modification:
public interface IIndexable<T> : IEnumerable<T>
{
T this[int index] { get; }
int Length { get; }
}
It also allows neat LINQ-like extension methods like Skip, Take and similar, which have better performance compared to LINQ due to the indexing capability.
In that case, you can implement a projection like this:
public class ProjectionIndexable<Tsrc, Ttarget> : IIndexable<Ttarget>
{
public ProjectionIndexable
(IIndexable<Tsrc> src, Func<Tsrc, Ttarget> projection)
{
_src = src;
_projection = projection;
}
#region IIndexable<Ttarget> Members
public Ttarget this[int index]
{
get { return _projection(_src[index]); }
}
public int Length
{
get { return _src.Length; }
}
#endregion
#region IEnumerable<Ttarget> Members
// create your own enumerator here
#endregion
}
And use it like this:
class AnotherClass
{
private IIndexable<string> _readonlyList;
public IIndexable<string> ReadonlyList
{
get { return _readonlyList; }
}
private List<SomeClass> _list;
public List<SomeClass> List
{
get { return _list; }
}
public AnotherClass()
{
_list = new List<SomeClass>();
_readonlyList = new ProjectionIndexable<SomeClass, string>
(_list.AsIndexable(), c => c.Age);
}
}
[Edit]
In the meantime, I posted an article describing such a collection on CodeProject. I saw you've implemented it yourself already, but you can check it out nevertheless and reuse parts of the code where you see fit.
Why don't you just return IEnumerable?
If you have access to LINQ (.NET 3.5) then just use a select()
public IEnumerable<string> Ages{
get{
return _innerList.Select(s => s.stringProperty);
}
}
in this case I normaly just use IEnumerable - if the collection is readonly and you don't need the Index-functionality you can just do somehting like this:
public IEnumerable<string> Ages
{
get
{
return this._innerList.Select(someObj => someObj.Age).ToArray();
}
}

How to create properties with "delegated" accessors?

I'm new to c# and have been puzzling over this for a couple of days. Basically I want to create a type of property with getter and setter logic delegated to a base type to which this parameter belongs.
This is just one application: a property whose value is set by, say, the registry or some config file.
The property handler on a get would do something like check a cached value (or not), retrieve the value if not cached, cache the value (or not) and return it.
Behavior for the setter would allow only the property handler to set the value (if possible).
Any suggestions? I've thought about using DefaultPropertyAttribute, but I can't quite see how not to write all the logic necessary with each accessor.
Looks like this is what I want: http://www.sharpcrafters.com/postsharp
"Write less code" Yup. That's it alright.
I'm not proud of it:
public abstract class HorribleBaseType
{
private Lazy<string> _connectionString;
private Action<string> _connectionStringSetter;
private Func<string> _connectionStringGetter;
public HorribleBaseType(
Func<string> connectionStringGetter,
Action<string> connectionStringSetter)
{
_connectionStringGetter = connectionStringGetter;
_connectionStringSetter = connectionStringSetter;
_connectionString = new Lazy<string>(connectionStringGetter);
}
public string ConnectionString
{
get { return _connectionString.Value; }
set
{
_connectionStringSetter(value);
_connectionString = new Lazy<string>(_connectionStringGetter);
}
}
}
public class HorribleType : HorribleBaseType
{
public HorribleType()
: base(() => MyConfiguration.ConnectionString,
(v) => MyConfiguration.ConnectionString = v) { }
}
100% untested.
UPDATE Using a combination of the above, and #hunter's answer, you could do something like:
public class DelegateProperty<T>
{
#region Fields
private readonly Func<T> _getter;
private readonly Action<T> _setter;
private Lazy<T> _lazy;
#endregion
#region Constructors
public DelegateProperty(Func<T> getter, Action<T> setter)
{
_getter = getter;
_setter = setter;
_lazy = new Lazy<T>(getter);
}
#endregion
#region Properties
public T Value
{
get { return _lazy.Value; }
set
{
_setter(value);
_lazy = new Lazy<T>(_getter);
}
}
#endregion
#region Operators
public static implicit operator T(DelegateProperty<T> prop)
{
return prop.Value;
}
#endregion
}
With that, you can now do something like:
class Program
{
static void Main(string[] args)
{
string name = "Matt";
var prop = new DelegateProperty<string>(
() => name,
value => name = value);
var test = new Test(prop);
Console.WriteLine(test.Name);
test.Name = "Ben";
Console.WriteLine(name);
Console.ReadKey();
}
}
public class Test
{
private readonly DelegateProperty<string> NameProperty;
public Test(DelegateProperty<string> prop)
{
NameProperty = prop;
}
public string Name
{
get { return NameProperty; }
set { NameProperty.Value = value; }
}
}
Using this stupid class:
public class Property<T>
{
Func<T> _func;
T _value;
bool _fetched;
public Property(Func<T> func)
{
_func = func;
}
public T Value
{
get
{
if (!_fetched)
{
_value = _func();
_fetched = true;
}
return _value;
}
set { _value = value; }
}
}
you can do something like this:
public class TestClass
{
Property<int> _propertyInt;
public int MyInt
{
get { return _propertyInt.Value; }
set { _propertyInt.Value = value; }
}
Property<string> _propertyString;
public string MyString
{
get { return _propertyString.Value; }
set { _propertyString.Value = value; }
}
}
Of course this won't handle every case but it might get you on the "right" track...

Can a method be overriden with a lambda function

Is there any way to override a class method with a lambda function?
For example with a class definition of
class MyClass {
public virtual void MyMethod(int x) {
throw new NotImplementedException();
}
}
Is there anyway to do:
MyClass myObj = new MyClass();
myObj.MyMethod = (x) => { Console.WriteLine(x); };
Chris is right that methods cannot be used like variables. However, you could do something like this:
class MyClass {
public Action<int> MyAction = x => { throw new NotImplementedException() };
}
To allow the action to be overridden:
MyClass myObj = new MyClass();
myObj.MyAction = (x) => { Console.WriteLine(x); };
No. However if you declare the method as a lambda in the first place, you can set it, though I would try to do that at initialization time.
class MyClass {
public MyClass(Action<int> myMethod)
{
this.MyMethod = myMethod ?? x => { };
}
public readonly Action<int> MyMethod;
}
This however cannot implement an interface that has a MyMethod declared, unless the interface specifies a lambda property.
F# has object expressions, which allow you to compose an object out of lambdas. I hope at some point this is part of c#.
No. Methods cannot be used like variables.
If you were using JavaScript, then yes, you could do that.
You can write this code:
MyClass myObj = new MyClass();
myObj.TheAction = x => Console.WriteLine(x);
myObj.DoAction(3);
If you define MyClass in this way:
class MyClass
{
public Action<int> TheAction {get;set;}
public void DoAction(int x)
{
if (TheAction != null)
{
TheAction(x);
}
}
}
But that shouldn't be too surprising.
Not directly, but with a little code it's doable.
public class MyBase
{
public virtual int Convert(string s)
{
return System.Convert.ToInt32(s);
}
}
public class Derived : MyBase
{
public Func<string, int> ConvertFunc { get; set; }
public override int Convert(string s)
{
if (ConvertFunc != null)
return ConvertFunc(s);
return base.Convert(s);
}
}
then you could have code
Derived d = new Derived();
int resultBase = d.Convert("1234");
d.ConvertFunc = (o) => { return -1 * Convert.ToInt32(o); };
int resultCustom = d.Convert("1234");
Depending on what you want to do, there are many ways to solve this problem.
A good starting point is to make a delegate (e.g. Action) property that is gettable and settable. You can then have a method which delegates to that action property, or simply call it directly in client code. This opens up a lot of other options, such as making the action property private settable (perhaps providing a constructor to set it), etc.
E.g.
class Program
{
static void Main(string[] args)
{
Foo myfoo = new Foo();
myfoo.MethodCall();
myfoo.DelegateAction = () => Console.WriteLine("Do something.");
myfoo.MethodCall();
myfoo.DelegateAction();
}
}
public class Foo
{
public void MethodCall()
{
if (this.DelegateAction != null)
{
this.DelegateAction();
}
}
public Action DelegateAction { get; set; }
}

ambiguous/conflicting constructors in generic class

I've got a generic class:
public class BaseFieldValue<T>
{
public BaseFieldValue()
{
//...
}
public BaseFieldValue(string value)
{
//...
}
public BaseFieldValue(T value)
{
//...
}
}
Fine. Except...
var myValue = new BaseFieldValue<string>("hello");
Oops. The undesired constructor is called. There's a number of ways to address the problem. What's the best solution?
I would probably make one of the overloads into a factory method:
public static BaseFieldValue<T> Parse(string value){}
You could do the following:
public class BaseFieldValue<T>
{
public struct Special
{
internal string m_value;
public Special(string value)
{
m_value = value;
}
}
public BaseFieldValue()
{
//...
}
public BaseFieldValue(Special value)
{
//...
}
public BaseFieldValue(T value)
{
//...
}
}
... or, you could add an extra ignored boolean parameter to your special constructor, just to disambiguate it.
Couldn't make Type Contraints do what I wanted, so my workaround is removing the ambiguous constructor while retaining the special case for string:
public class BaseFieldValue<T>
{
public BaseFieldValue()
{
//...
}
public BaseFieldValue(T value)
{
//however many things you need to test for here
if (typeof(T) == typeof(string))
{
SpecialBaseFieldValue(value.ToString());
}
else
{
//everything else
}
//...
}
private void SpecialBaseFieldValue(string value)
{
//...
}
}
A nasty hack, but probably no worse than any of the alternatives:
public class BaseFieldValue<T>
{
public BaseFieldValue()
{
// ...
}
public BaseFieldValue(StringWrapper value)
{
// ...
}
public BaseFieldValue(T value)
{
// ...
}
public class StringWrapper
{
private string _value;
public static implicit operator string(StringWrapper sw)
{
return sw._value;
}
public static implicit operator StringWrapper(string s)
{
return new StringWrapper { _value = s };
}
}
}
And now it can be used as you need:
// call the generic constructor
var myValue = new BaseFieldValue<string>("hello");
// call the string constructor
var myValue = new BaseFieldValue<int>("hello");
May be you can try thi:
var myValue = new BaseFieldValue<Object>("hello" as Object);

Categories

Resources