I've been studying up on static reflection with LINQ expressions - very cool!
One thought I had - is it possible for one class to 'generate' fields on one class based on static reflection done on another class? I'm thinking specifically of the Builder pattern I've seen here many times. I would like to do a fluent-nhibernate-style property registration that 'generates' fields on the builder that match the class I want to build. Soemthing like this:
public class Color
{
private Color()
{
}
public string Name { get; private set; }
public class Builder : BuilderBase<Color>
{
public Builder()
{
Property(x => x.Name);
}
public Build()
{
return built_up_color;
}
}
}
and support constructor syntax like this:
Color c = new Color.Builder() { Name = "Red" }.Build();
The point of all this is to reduce the number of times I have to repeat defining the properies of Color. I played with this:
public class Color
{
private Color()
{
}
public string Name { get; private set; }
public class Builder
{
private Color _color = new Color();
public string Name
{
get { return _color.Name; }
set { _color.Name = value; }
}
public Build()
{
return _color;
}
}
}
which certainly works AND lists the properties the same # of times but feels wordier and less flexible. It seems like I should be able to do something anonymous-type-y here?
Worth pointing out that Having a class called Color clashing with the System.Drawing.Color is probably a bad idea.
It is very likely to lead to confusion in others (worse still System.Drawring.Color has value semantics whereas your class has reference semantics which can lead to further confusion)
I would point out that what you really want is Named Optional Arguments. I would suggest that putting in cumbersome Builder classes now will be more effort and made it more painful to move to these once you get to c# 4.0. Instead make the constructors that are required (or if need be to avoid type signature collisions static factory methods on the class)
I think it's impossible, you can't generate members except by declaring them explicitly. Bite the bullet and declare a constructor for Color.
PS: I think static reflection is a misnomer, the only thing that's static is the lookup of the member you want to reference — a good thing as far as it goes, but that's not very far.
less code to write but using reflection to set the values.
The trick is to use collection initializers. it is typesafe.
public class Color
{
private Color()
{
}
public string Name { get; private set; }
public int Prop2 { get; private set; }
public class Builder : Builder<Color>
{
public Builder()
{
// possible
_instance.Name = "SomeDefaultValue";
}
}
}
class Builder<T> : IEnumerable<string>
{
protected T _instance = Activator.CreateInstance(typeof(T));
public void Add<TProperty>(Expression<Func<T, TProperty>> prop, TProperty value)
{
StaticReflection.GetPropertyInfo(prop).SetValue(_instance, value, null);
}
public static implicit operator T(Builder<T> builder)
{
return builder.Build();
}
public T Build()
{
return _instance;
}
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
// e.g. return iterator over the property names
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<string>)this).GetEnumerator();
}
}
and call syntax
var color = new Color.Builder
{
{ x => x.Name, "foo" },
{ x => x.Prop2, 5 }
}.Build();
// or
var color = new Builder<Color>
{
{ x => x.Name, "foo" },
{ x => x.Prop2, 5 }
}.Build();
// or
Color color = new Builder<Color>
{
{ x => x.Name, "foo" },
{ x => x.Prop2, 5 }
};
Related
I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());
Is there an elegant (or any) way to achieve following in C#?
Let's have a class ItemBase (further derivable to Item1, Item2...), which does not allow direct instantiation (non-public construction) - to prevent user to create any 'untracked' instance of Item*.
Let's have a non-static class Manager, whose instances (multiple ones allowed) only can create and provide instances of Item* (because they keep track of produced instances and do some additional work).
Let's have an optional requirement: The Manager instances would like to manipulate non-public members of the managed Item instances (similar like the Manager would be a friend of Item*).
It would be nice if the Manager is not forced to be derivation of Item*.
It would be nice if there is as little reflection as possible.
Notes:
If possible, please consider this as a question raising from process of thinking how to implement particular problem solution in a best and elegant way. I would like it to be general and no, I don't have sources and yes, I have already tried some variants, but none of them satisfied my needs. Thank you.
As far as I know, there is no acceptable friend alternative (any of internal and InternalsVisibleToAttribute seems to be good), so the ItemBase just provides the 'special' (but public) modification methods and the user must be aware, these methods are not for him :o(
I like this solution, but I'm not able to invent, how to allow multiple Manager instances using it.
I think this might answer your problem :
public class ItemBase
{
protected ItemBase()
{
}
public void PublicMethod() { }
public int PublicProperty { get; set; }
}
public class Factory
{
private class PrivateItemBase : ItemBase
{
public void PrivateMethod() { }
public int PrivateProperty { get; set; }
}
public Factory(int id)
{
}
public IEnumerable<ItemBase> Items { get; private set; }
public ItemBase CreateItem()
{
PrivateItemBase rValue = new PrivateItemBase();
rValue.PrivateMethod();
rValue.PrivateProperty = 4;
return rValue;
}
}
Ok, giving up. If this might help to fully understand the purpose, there is the less bad solution I've (currently) ended up. Passing the creation functions is done via static constructors (which are not accessible by the users), unfortunately the ugly thing is their invocation...
Any idea how to make it better?
The item definitions:
namespace SpecialFactory
{
public enum ItemType
{
Item1,
Item2,
// ... Anyone deriving the Item* should add an item here
}
public abstract class ItemBase
{
public abstract ItemType Id {get;}
public static void RegisterAllCreators()
{
// Force static constructors invocation
var it = Item1.ClassId | Item2.ClassId; // Anyone deriving the Item* should ensure invocation of Manager.RegisterCreator
}
}
public class Item1 : ItemBase
{
static Item1()
{
Manager.RegisterCreator(ItemType.Item1, () => new Item1());
}
protected Item1()
{
}
public static ItemType ClassId => ItemType.Item1;
public override ItemType Id => ClassId;
}
public class Item2 : ItemBase
{
static Item2()
{
Manager.RegisterCreator(ItemType.Item2, () => new Item2());
}
protected Item2()
{
}
public static ItemType ClassId => ItemType.Item2;
public override ItemType Id => ClassId;
}
}
The manager:
namespace SpecialFactory
{
public class Manager
{
static Manager()
{
ItemBase.RegisterAllCreators();
}
protected static Dictionary<ItemType, Func<ItemBase>> creators = new Dictionary<ItemType, Func<ItemBase>>();
protected readonly List<ItemBase> managedItems = new List<ItemBase>();
protected ItemBase CreateItem(ItemType type)
{
ItemBase item = null;
if (creators.ContainsKey(type))
{
if ((item = creators[type]()) != null)
managedItems.Add(item);
}
return item;
}
public static void RegisterCreator(ItemType type, Func<ItemBase> creator)
{
if (!creators.ContainsKey(type))
creators[type] = creator;
}
public Manager()
{
}
public ItemBase Test(ItemType type)
{
// var notAllowed = new Item1();
var allowed = CreateItem(type);
return allowed;
}
}
}
The test:
namespace SpecialFactory
{
class Program
{
static void Main(string[] args)
{
var m1 = new Manager();
var m2 = new Manager();
var i1 = m1.Test(ItemType.Item1);
var i2 = m2.Test(ItemType.Item2);
}
}
}
I have a class with a lot of properties of type IDbSet<SomeClass>:
public InMemoryContext : IContext
{
public IDbSet<ClassA> ClassASet { get; set; }
public IDbSet<ClassB> ClassBSet { get; set; }
[...]
public void SaveChanges()
{
//TODO: this is relevant part
}
}
All these properties are instantiated in the constructor:
public InMemoryContext
{
ClassASet = new InMemoryDbSet<ClassA>();
[...]
}
InMemoryDbSet has one relevant method for this question:
public class InMemoryDbSet<T> : IDbSet<T> where T : class
{
public void SaveChanges()
{
[...]
}
}
I'd like to get all properties that are IDbSet and call SaveChanges() on them in a loop, so I don't need to repeat all set names second time.
I tried with reflection but as my properties are generic I can't get it to work. I tried making ClassA and ClassB deriving from same common interface but still no luck.
Is it actually possible to do it without explicitly specifying all sets? What should I change to achieve this result?
I imagine the pseudocode to be like:
public void SaveChanges()
{
foreach(var set in GetDbSetsFromClass(this))
{
set.SaveChanges();
}
}
With reflection I tried:
public void SaveChanges()
{
SaveChangesCalled = true;
var properties = GetType().GetProperties().Where(p => p.PropertyType.IsInterface && typeof(IDbSet<IEntity>).IsAssignableFrom(p.PropertyType)).Cast<InMemoryDbSet<IEntity>>();
foreach (var property in properties)
{
CallSaveChanges(property);
}
}
And the list is empty
public bool SaveChangesCalled { get; set; }
private static void CallSaveChanges<T>(InMemoryDbSet<T> set) where T : class
{
set.SaveChanges();
}
EDIT: The public properties must remain visible at the top level of InMemoryContext class as this is restricted by the interface defining EF context.
Your code doesn't work because IDbSet<Class> is not assignable to IDbSet<IEntity>, because IDbSet<T> is not covariant.
What you want is to find properties whose type's generic definition is IDbSet<>.
var properties = typeof (InMemoryContext)
.GetProperties()
.Where(p => p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition() == typeof (IDbSet<>));
To invoke your CallSaveChanges method, you'll need this:
foreach(var proparty in properties)
{
var value = property.GetValue(this);
var entityType = property.PropertyType.GetGenericArguments().First();
var callSaveChanges = this.GetType()
.GetMethod("CallSaveChanges", BindingFlags.NonPublic | BindingFlags.Static);
var constructedCallSaveChanges = callSaveChanges.MakeGenericMethod(entityType );
constructedCallSaveChanges.Invoke(null, BindingFlags.NonPublic | BindingFlags.Static, null, new object[]{ value }, CultureInfo.InvariantCulture);
}
That being said, I don't think this scenario warrants the usage of reflection.
For a simple solution you could try something like this
public InMemoryContext
{
public Dictionary<string, object> allSets = new Dictionary<string, object>();
public InMemoryContext()
{
allSets.Add("classA", new InMemoryDbSet<ClassA>());
allSets.Add("classB", new InMemoryDbSet<ClassB>());
[...]
}
public IDbSet<ClassA> ClassASet { get
{
return allSets["classA"];
}
set
{
allSets["classA"] = Value
}
}
[...]
public void SaveChanges()
{
//TODO: this is relevant part
foreach(var kvp in allSets)
{
kvp.Value.SaveChanges();
}
}
}
Some things maybe wrong since it's just off top of my head.. but you should get the idea
Suppose that the scenario doesn't allow to implement an immutable type. Following that assumption, I'd like opinions / examples on how to properly design a type that after it's consumed, becomes immutable.
public class ObjectAConfig {
private int _valueB;
private string _valueA;
internal bool Consumed { get; set; }
public int ValueB {
get { return _valueB; }
set
{
if (Consumed) throw new InvalidOperationException();
_valueB = value;
}
}
public string ValueA {
get { return _valueA; }
set
{
if (Consumed) throw new InvalidOperationException();
_valueA = value;
}
}
}
When ObjectA consumes ObjectAConfig:
public ObjectA {
public ObjectA(ObjectAConfig config) {
_config = config;
_config.Consumed = true;
}
}
I'm not satisfied that this simply works, I'd like to know if there's a better pattern (excluded, as said, making ObjectAConfig immutable by design from begin).
For example:
can make sense define a monad like Once<T> that allow the wrapped value to be initialized only once?
can make sense define a type that returns the type itself changing a private field?
What you are implementing sometimes goes under the name "popsicle immutability" - i.e. you can freeze it. Your current approach will work - indeed I use that pattern myself in numerous places.
You can probably reduce some duplication via something like:
private void SetField<T>(ref T field, T value) {
if (Consumed) throw new InvalidOperationException();
field = value;
}
public int ValueB {
get { return _valueB; }
set { SetField(ref _valueB, value); }
}
public string ValueA {
get { return _valueA; }
set { SetField(ref _valueA, value); }
}
There is another related approach, though: a builder. For example, taking your existing class:
public interface IConfig
{
string ValueA { get; }
int ValueB { get; }
}
public class ObjectAConfig : IConfig
{
private class ImmutableConfig : IConfig {
private readonly string valueA;
private readonly int valueB;
public ImmutableConfig(string valueA, int valueB)
{
this.valueA = valueA;
this.valueB = valueB;
}
}
public IConfig Build()
{
return new ImmutableConfig(ValueA, ValueB);
}
... snip: implementation of ObjectAConfig
}
Here there is a truly immutable implementation of IConfig, and your original implementation. If you want the frozen version, call Build().
I'm experimenting with an API for publishing values at a given time (tuples of value and time). These samples will be used by a data viewer (e.g. a graph).
I want to associate the value with a Quantity and a Unit, for example length in meters. That way my "viewer" can scale it appropriately.
I'm looking for a sort of hierarchical enum, like this:
enum Quantity
{
Mass.Kg,
Mass.g,
Length.m,
Length.mm
}
But this doesn't exist in C#.
I'm not sure the best pattern to express this and I've come up with the following. Is there a recognised, or better way to do this?
using System;
using Moq;
namespace ConsoleApplication26
{
class Program
{
static void Main(string[] args)
{
//use a Mock to play with the API
Mock<ITelemetryPublisherFactory> mockTelemetryPublisherFactory = new Mock<ITelemetryPublisherFactory>();
var telemetryPublisherFactory = mockTelemetryPublisherFactory.Object;
//example usages
var massTelemetryPublisher = telemetryPublisherFactory.GetChannelSamplePublisher<Double>("My Mass", Mass.Kg);
massTelemetryPublisher.PublishChannelSampleAtTimeNow(83.4);
var lengthTelemetryPublisher = telemetryPublisherFactory.GetChannelSamplePublisher<Int32>("My Height", Length.μm);
lengthTelemetryPublisher.PublishChannelSampleAtTimeNow(1800000);
//10 years time..
lengthTelemetryPublisher.PublishChannelSampleAtTimeNow(1800000);
massTelemetryPublisher.PublishChannelSampleAtTimeNow(120.1);
}
}
public interface ITelemetryPublisherFactory
{
ITelemetryPublisher<T> GetChannelSamplePublisher<T>(String channelName, Quantity quantity);
}
public interface ITelemetryPublisher<T>
{
void PublishChannelSampleAtTimeNow(T sampleValue);
}
public abstract class Quantity {}
public class Mass : Quantity
{
private enum Unit
{
g,
Kg
}
private readonly Unit _unit;
private Mass(Unit unit)
{
_unit = unit;
}
public static Quantity Kg {get { return new Mass(Unit.Kg); }}
public static Quantity g { get { return new Mass(Unit.g); } }
public override string ToString()
{
return String.Format("Mass.{0}", _unit);
}
}
public class Length : Quantity
{
private enum Unit
{
m,
mm,
μm,
beardSecond
}
private readonly Unit _unit;
private Length(Unit unit)
{
_unit = unit;
}
public static Quantity m { get { return new Length(Unit.m); } }
public static Quantity mm { get { return new Length(Unit.mm); } }
public static Quantity μm { get { return new Length(Unit.μm); } }
public static Quantity beardSecond { get { return new Length(Unit.beardSecond); } }
public override string ToString()
{
return String.Format("Length.{0}", _unit);
}
}
}
I think it's better to create a Unit class for the unit of measure and a Quantity class that associates a unit of measure with an amount. Look at the Quantity pattern for the idea. Since you also want to record the "type" of the unit of measure, you could create a UnitType class that records that information:
public sealed partial class UnitType {
public string Name { get; private set; }
public UnitType(string name) {
Name = name;
}
}
public sealed partial class Unit {
public string Name { get; private set; }
public UnitType Type { get; private set; }
public Unit(string name, UnitType type) {
Name = name;
Type = type;
}
}
(You should make them proper value types by overriding Equals and GetHashCode)
The Unit class can be extended to provide for e.g. conversions, compound units, formatting and parsing.
Then, you can define the common cases inside the classes:
public partial class UnitType {
public static readonly UnitType Mass = new UnitType("Mass");
public static readonly UnitType Length = new UnitType("Length");
}
public partial class Unit {
public static readonly Unit Grams = new Unit("g", UnitType.Mass);
public static readonly Unit Kilos = new Unit("kg", UnitType.Mass);
// ...
}
Or define your "hierarchies" with static classes:
public static class Mass {
public static readonly UnitType Type = new UnitType("Mass");
public static readonly Unit Grams = new Unit("g", Type);
public static readonly Unit Kilos = new Unit("kg", Type);
...
}
public static class Length ...
The Quantity class would also be an immutable value type (just showing its usage):
var eniacWeight = new Quantity(27, Mass.Tons);
Or you could use extension methods to create Quantitys:
var eniacWeight = 27.Tons();
(from ENIAC)
This is not possible. Enums are primitive types and cannot inherit from other enums, as inheritance is a property of objects.
Hierarchical enum isn't possible, as noted above. If you're exclusively using metric, though, you can utilise standard prefixes if it helps.
enum MeasurementUnits
{
Gram,
Metre,
Litre,
Hectare
// etc
}
enum MeasurementPrefix
{
Milli,
Natural,
Kilo,
Mega
// etc
}
This may not be precisely what you want, but it will provide the type of 'grouping' that you might be looking for (e.g. group measurements that are about length, weight etc by checking their 'units' value).
Your suggested approach seems reasonable to me, and I use something similar in a project of mine. However, I keep the actual value part of the object, and I use struct instead of class, since they are naturally value types. Inheritance is not necessary here (and not possible with structs, anyways), so I use an interface to create a contract and act as a constraint when needed (I called it IUnitOfMeasure).
I do not recommend creating one enum with all the units of the various types of measurement combined; it is hell validating the unit to make sure someone didn't reference a Mass unit when working with Length.
public interface IUnitOfMeasure<TThis>
where TThis : IUnitOfMeasure<TThis>
{
TThis ConvertTo(TThis value);
}
public struct Mass : IUnitOfMeasure<Mass>
{
public enum Units
{
Gram,
Kilogram
}
private double _value;
private Mass.Units _unit;
public double Value { get { return _value; } }
public Mass.Units Unit { get { return _unit; } }
public Mass(double value, Mass.Units unit)
{
_value = value;
_unit = unit;
}
public Mass ConvertTo(Mass value)
{
switch(value.Unit)
{
case Units.Gram:
return new Mass(Unit == Units.Gram ? Value : Value/1000, Units.Gram);
case Units.Kilogram:
return new Mass(Unit == Units.Gram ? Value*1000 : Value, Units.Kilogram);
default:
throw new NotImplementedException();
}
}
public override string ToString()
{
return string.Format("{0} {1}", Value, Unit);
}
public static readonly Mass G = new Mass(0, Units.Gram);
public static readonly Mass Kg = new Mass(0, Units.Kilogram);
}
Usage:
var kg = new Mass(5.0, Mass.Units.Kilogram);
Console.WriteLine(kg); // writes "5 Kilogram"
var g = kg.ConvertTo(Mass.G);
Console.WriteLine(g); // writes ".005 Gram"
If you don't care about keeping the value, and just want to keep enum/static values in a central place:
public static class UnitOfMeasure
{
public enum Mass
{
Gram,
Kilogram
}
public enum Length
{
Meter,
Kilometer
}
// etc.
}
Usage: var unit = UnitOfMeasure.Mass.Kilogram;
You cannot introduce inheritance with enums. Enums are just a convenience mechanism to allow you to use meaningful textual identifiers in your code. From The code you have, I suggest you either use an enum like;
public enum UnitOfMeasure
{
MassGrams,
MassKg,
LengthMM,
LengthCM,
. . .
}
Or split it out to where it's appropriate, so that Mass and Length are defined separately for example.
The 'inheritance' is just something you've introduced in your thinking about this problem, but it isn't necessary to your solution. When you want to deal with Mass, you only look at the flags/enums appropriate to mass.