Object Initialization and "Named Constructor Idiom" - c#

Ok. So I have a list of values, and I'd like to do something like the following:
MyObjectValues
.Select(currentItems=>new MyType()
{
Parameter1 = currentItems.Value1,
Parameter2 = currentItems.Value2
});
So here's the problem. I need the above example to work with named constructors, such as:
MyObjectValues
.Select(currentItems=>MyType.GetNewInstance()
{
Parameter1 = currentItems.Value1,
Parameter2 = currentItems.Value2
});
Is there any way I can do that? Basically, I have a static method I need to call to get the object instance back, and I'd like to initialize it as above.
EDIT: I don't have an easy way to modify the interface of MyType at present, so adding new function calls (while probably the 'best' approach) isn't very practical at the moment.

Unfortunately there's no direct support for this in C# 3.0. Object initializers are only supported for constructor calls. However, you might consider the Builder pattern. In my Protocol Buffers port, I support it like this:
MyType foo = new MyType.Builder {Parameter1 = 10, Parameter2 = 20}.Build();
So your example would become:
MyObjectValues.Select(currentItems => new MyType.Builder
{
Parameter1 = currentItems.Value1,
Parameter2 = currentItems.Value2
}.Build());
Of course, it means writing the nested Builder type, but it can work quite well. If you don't mind MyType being strictly speaking mutable, you can leave an immutable API but make an instance of Builder immediately create a new instance of MyType, then set properties as it goes (as it has access to private members), and then finally return the instance of MyType in the Build() method. (It should then "forget" the instance, so that further mutation is prohibited.)

I'm sure someone will think of a clever way to do it in pre 4.0 C#, but I just read Sam Ng's blog post on named parameters in C# 4.0. This should solve your problem. It would look like this:
MyObjectValues.Select(currentItems=>MyType.GetNewInstance(
Parameter1:currentItems.Value1,
Parameter2:currentItems.Value2));
EDIT
Forgot to mention, what makes this useful is that you can set defaults for the parameters, so you don't have to pass them all. The blog post is a good short summary.

Update: how about a factory:
MyObjectValues.Select(currentItems=>MyTypeFactory.GetNewInstance(currentItems.Value1,
currentItems.Value2));
public static class MyTypeFactory
{
public static MyType GetNewInstance(
typeofvalue1 value1,
typeofvalue2 value2)
{
return new MyType { Parameter1 = value1, Parameter2 = value2 };
}
}

Related

Factory driven by enum attributes

I have a situation where a factory pattern seems appropriate like this:
enum Food {
Cake,
Cookies,
Milk,
CannedBeans
}
public static class FoodMetaDataFactory{
public static IFood GetMetaData(Food foodType){ //takes a food enum value as a parameter
switch(foodType){
case Food.Milk:
return new MilkMetaData();
case Food.CannedBeans:
return new CannedBeansMetaData();
case Food.Cookies:
return new CookiesMetaData();
case Food.Cake:
return new CakeMetaData();
}
}
}
However, I'd rather have more declarative pattern like this:
enum Food {
[FoodMetaDataAttribute(typeof(CakeMetaData))]
Cake,
[FoodMetaDataAttribute(typeof(CookiesMetaData))]
Cookies,
[FoodMetaDataAttribute(typeof(MilkMetaData))]
Milk,
[FoodMetaDataAttribute(typeof(CannedBeansMetaData))]
CannedBeans
}
public static class FoodMetaDataFactory{
public static IFood GetMetaData(Food foodType){ //takes a food enum value as a parameter
//reflectively retrieve FoodMetaDataAttribute
Type enumType = typeof(Food);
var memInfo = enumType.GetMember(foodType.ToString());
//assume one item returned
var foodMetaDataAttributes = memInfo[0].GetCustomAttributes(typeof(FoodMetaDataAttribute),
false);
// now access the property telling us the concrete type of the metadata class(this is the type passed in the attribute's declaration
Type targetType = ((FoodMetaDataAttribute)foodMetaDataAttributes[0]).MetaDataProviderType;
//not done yet, now we need to reflectively instantiate targetType, something like this
ConstructorInfo ctor = targetType.GetConstructor(new[] { });
//invoke the constructor, returning concrete instance such as CakeMetaData
return ctor.Invoke(new object[] {}) as IFood;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class FoodMetaDataAttribute : Attribute
{
public FoodMetaDataAttribute(Type metaDataProviderType){
MetaDataProviderType = metaDataProviderType;
}
public Type MetaDataProviderType { get; set; }
}
I like this because it is clear to anyone adding new values to the enum that they need a meta data class and declare it in the attribute. This IMO is better than having to remember to modify the switch case in a factory.
It seemed simple at first until I started to think about the implementation of GetMetaData that has to reflectively retrieve the attribute, the typeof parameter, and then reflectively instantiate the MetaData class. I'm not experienced in creating attribute classes, so the primary driver of this question is a hope that maybe there's a simpler way to accomplish this with attributes. If attribute classes didn't have so many restrictions, such as on using generic types, I'd have this done in a way I liked with some compile time safety.
This proposed solution has no compile time safety. You can pass in types to the attribute that don't implement IFood, which is the minimum requirement for MetaData classes such as MilkMetaData. If attributes allowed generic type parameters I'd use that instead of typeof and could apply a where T:IFood
Is there a better way to utilize attributes to accomplish this mapping from enum value to concrete class?
What I usually do in these cases is create a dictionary of factories, e.g.:
private IDictionary<MyEnum, Func<IMyInterface>> Factories = new Dictionary<MyEnum, Func<IMyInterface>> {
{ MyEnum.MyValue, () => new MyType() },
// etc.
}
Simple and easy to maintain, extend or validate. You can create instance by doing:
IMyInterface instance;
if(!Factories.TryGetValue(enumValue, out instance))
throw new Exception(string.Format("No factory for enum value {0}", enumValue));
return instance;
Note that separating the enum from the actual instance should be a good thing (split implementation from data). Otherwise, I suggest you simply pass on the actual type to a generic method.
I'm not 100% sure that there is not a completely different approach that would be better, but there is just couple things you can improve in your current code:
You can use Activator.CreateInstance(type) instead of getting the constructor:
return Activator.CreateInstance(targetType) as IFood;
You can also consider some kind of cache, to avoid doing all the reflection-related work on every single call. You can either store a single instance of concrete IFood implementation for each enum value, using simple dictionary:
public static class FoodMetaDataFactory
{
private static Dictionary<Food, IFood> _cache = new Dictionary<Food, IFood>();
public static IFood GetMetaData(Food foodType)
{ //takes a food enum value as a parameter
IFood value;
if (!_cache.TryGetValue(foodType, out value))
{
lock (_cache)
{
if (!_cache.TryGetValue(foodType, out value))
{
var enumType = typeof(Food);
var memberInfo = enumType.GetMember(foodType.ToString());
var foodMetaDataAttributes = memberInfo[0].GetCustomAttributes(typeof(FoodMetaDataAttribute), false);
var targetType = ((FoodMetaDataAttribute)foodMetaDataAttributes[0]).MetaDataProviderType;
value = Activator.CreateInstance(targetType) as IFood;
_cache.Add(foodType, value);
}
}
}
return value;
}
}
or if you need each call to return fresh instance instead of shared one, you can use Expression Trees, to generate a Func<IFood> lambda expression when GetMetaData is called for the first time for given enum value, and call it later instead of reflection-processing.
About compile-time safety: I'm afraid you'd have to write your own custom check about that, e.g. as FxCop custom rule, or maybe something using Roslyn, if you're using newest (beta) version of Visual Studio.
New here. To start from the end, If you want to use these Enum values for display, the best way to do it is to decorate them with an attribute that is a display string (or CSV), but if the values need to be complex, you should be using a Factory Method that creates new Food types. A base class can contain common values while each successive Child class has specifics that can then always be fed to the UI mechanism.
This only works if either each type creates it's own View or the views are common between types. This is similar to dependency injection in the second idea.
But if you want to add additional enums that represent code paths, you have to ALWAYS update your Controller\ViewModel unless there is some generic model that is always used for display.
I don't know your code base, so I don't know what type of refactoring would be required for a Factory or Adapter pattern.

Delphi Class of in C#

I know this question has been asked before, but I have yet to see a short, clear answer, so I'm hoping they won't remove this question and I will now get a clear answer:
I am currently working in C# 5.0; .NET 4.5; VS 2012. I am mostly a Delphi guy although I've done lots with C#.
In Delphi I have written hundreds of class factories that use the following sort of design (MUCH SIMPLIFIED HERE):
unit uFactory;
interface
type
TClassofMyClass = class of TMyClass;
TFactoryDict = TDictionary<TMyEnum, TClassofMyClass>;
var fDict:TFactoryDict;
implementation
procedure initDict;
begin
fDict:=TFactoryDict.create;
fDict.add(myEnum1, TMyClass1);
fDict.add(myEnum2, TMyClass2);
fDict.add(myEnum3, TMyClass3);
end;
function Factory(const aEnum: TMyEnum): TMyClass;
var
ClassofMyClass: TClassofMyClass;
begin
if fDict.TryGetValue(aEnum, ClassofMyClass) then
result := ClassofMyClass.Create(aParam);
end;
end.
Now: HOW do I do something like this in C#?! Seems there is NO 'class of ' type in C#. Am I missing something? How can I implement this type of class factory simply and elegantly in C#? This design can be implemented in Python as well - why should C# be worse?!
You can use Type:
Dictionary<ClassEnum, Type> TypeDictionary = new Dictionary<ClassEnum, Type>();
public void InitDictionary()
{
TypeDictionary.Add(ClassEnum.FirstClass, typeof(FirstClass));
//etc...
}
public object Factory(ClassEnum type)
{
if (!TypeDictionary.ContainsKey(type))
return null;
var constructor = TypeDictionary[type].GetConstructor(....);
return constructor.Invoke(....);
}
But I think you should use a generic method:
public T Factory<T>(): where T is MyBaseClass
{
var type = typeof(T);
var constructor = type.GetConstructor(....);
return constructor.Invoke(....) as T;
}
Here is a variety for parameterized construction:
public T Factory<T>(params object[] args): where T is MyBaseClass
{
var argList = new List<object>(args);
var type = typeof(T);
var argtypes = argList.Select(o => o.GetType()).ToArray();
var constructor = type.GetConstructor(argtypes);
return constructor.Invoke(args) as T;
}
And of course; As with the first example, this will throw a nullpointerexception if it can't find a matching constructor...
class Potato
{
}
class Potato1 : Potato
{
public Potato1(object[] param) { }
}
class Potato2 : Potato
{
public Potato2(object[] param);
}
enum MyEnum
{
E1, E2
}
Dictionary<MyEnum, Func<object[], Potato>> dict = new Dictionary<MyEnum, Func<object[], Potato>>(){
{MyEnum.E1,(d)=>new Potato1(d)},
{MyEnum.E2,(d)=>new Potato2(d)}
};
Potato Factory(MyEnum e, object[] param)
{
return dict[e](param);
}
If i understood you correct you want to have a reference to a static class. This is not possible in c#.
just one example of factory method implementation:
http://www.codeproject.com/Tips/328826/implementing-Factory-Method-in-Csharp
The C# language does not support meta classes.
So you'll have to implement your factory in another way. One way is to use a switch statement on an enum:
switch (aEnum)
{
case myEnum1:
return new MyClass1();
case myEnum2:
return new MyClass2();
.....
}
Another commonly used option is to do it with reflection which would allow you to write code closer to what you are used to doing.
And yet another option is to replace your dictionary of classes with a dictionary of delegates that return a new instance of your object. With lambda syntax that option yields very clean code.
The disadvantage of reflection is that you give up compile time type safety. So whilst the reflection based approach is probably closest to the Delphi code in the question, it's not the route that I personally would choose.
Rather than trying to shoe horn your Delphi solution into a language that does not want that approach, I suggest you look for the most idiomatic C# solution. Start with a web search for class factory.

Which approach for kind of Singleton is better?

My program instantiates an object with parameters passed in command line. I need to be able to instantiate an object with those parameters but yet it should be created only once. I've read these posts 1 & 2 but I still didn't understand which approach is better:
1 - var myInstance = MyClass.Instance.Create("param1", "param2");
OR
2 - var myInstance = MyClass.Instance;
myInstance.setParam1("param1");
myInstance.setParam2("param2");
In the first approach the new instance for each different pair of parameters passed to Create will be created. The only way to prevent this is to set flag inside Create that will return the created instance.
In 2nd approach the problem is what if constructor of MyClass will depend on param1 and param2?
So, what would you suggest?
You can use the first approach too:
MyClass.Instance.Create("param1", "param2")
with slight difference, which may make parameters not mandatory, if you need, using Named Parameters, like say:
MyClass.Instance.Create(param1 = "param1", param2 = "param2")
So you can avoid using parameters at all (during call) and lay on default values provided in declaration.
I'd:
create an immutable Config class with a public constructor that takes the parameters
create a static method Config ParseCommandLine(string) that turns a command-line into a Config object.
Since this is a pure function (no side-effects, no global state) it's easy to test this.
a static method Config ParseCommandLine() that gets the actual command line and calls the above method (a bit ugly, since it accesses global mutable state)
Finally use Config.SetInstance(ParseCommandLine()) to back the Instance property on your "singleton". This is a bit ugly, but using a singleton is ugly in the first place.
This "singleton" doesn't really enforce that there is a single config, but it's more of a default instance. In my experience real singletons are rarely needed, and even the default instance is kind of a hack.
You'd end up with something like this:
public class Config
{
public string Param1{get;private set;}
public int Param2(get;private set;}
public Config(string param1, int param2)
{
Param1=param1;
Param2=param2;
}
// take a string[] if you prefer to use Environment.GetCommandLineArgs
public Config ParseCommandLine(string commandLine)
{
string param1=...;
int param2=...;
return new Config(param1:param1, param2:param2);
}
public Config ParseCommandLine()
{
return ParseCommandLine(Environment.CommandLine);
}
}
I'd also consider throwing the static Instance property away, in favour of injecting the configuration to the objects that need it. But for a small program that may be over-engineering.
In your case it is better to use no Singleton.
Singleton's Intent:
Ensure that only one instance of a class is created.
Provide a global point of access to the object.
http://www.oodesign.com/singleton-pattern.html
Use a private static attribute as a flag if you need to ensure that only one instance is allowed.
Update:
public class MyClass {
private static boolean isAlreadyInitiated = false;
public MyClass() {
if(isAlreadyInitiated){
throw new IllegalStateException("Only one instance allowed.");
}
isAlreadyInitiated = true;
}
}

C# simpler run time generics

Is there a way to invoke a generic function with a type known only at run time?
I'm trying to do something like:
static void bar()
{
object b = 6;
string c = foo<typeof(b)>();
}
static string foo<T>()
{
return typeof (T).Name;
}
Basically I want to decide on the type parameter only at run time, but the function I'm calling depends on the type parameter.
Also I know this can be done with reflections... but it's not the nicest solution to the problem...
I'm sort of looking for dynamic features in C#...
I'm writhing a bridge between two classes the first one is basically a big tree with different types of of objects (composite by interface) the other is a sort of a "super visitor".
the supper visitor accepts key-value dictioneries that map types to object it looks like:
dic.Add(object value)
and T is not necessarily the type of the value... a lot of times it isn't...
I know it's written poorly, but i can't fix it...
I can work around it, but only at runtime...
I already did it with reflections, but if there's a better way to do it without them i would be happy to learn...
Thank you
This is a bit of a hack but you can get dynamic to do the reflection work for you by something like,
class Program
{
static void Main(string[] args)
{
var b = 6;
var t = (dynamic)new T();
var n = t.Foo(b);
}
class T
{
public string Foo<T>(T a)
{
return typeof(T).Name;
}
}
}
Here the dynamic call will extract the type of b and use it as a type parameter for Foo().
You can use dynamic keyword if you're using .NET 4. In a word, the type of the variable will be resolved at run time so it is a super generic type ;) You can read a article here or read the MSDN documentation
Saly refelction is THE solution to the problem, whether it is nice or not is irrelevant here. It is the runtime designed mechanism to achieve exactly this. As there is no parameter or generics to use as input, this is the only way to do it - it is also senseless. As in: your example is bad. Because in the example the type is hardcoded.
If the method where b exists has b as generic parameter, the type is available for passing to foo. If not - reflection is THE way to go, albeit the syntax looks clumsy. Only one time, though.
This I believe is the only way:
var foo = typeof(Foo<>).MakeGenericType(typeof (bar));
You can set up a class which takes a type parameter at run time which can be used in the methods in that class.
public class GenericClass<T>()
{
ICommonInterface TheObject;
public GenericClass(T theObject)
{
TheObject = theObject;
}
public string GetName()
{
return TheObject.Name;
}
}
But this is only really useful if the Types being passed in share interfaces so have common properties between them. In your example it seems that relection is the answer as depending on the type you want to access specific properties.

Is the StaticFactory in codecampserver a well known pattern?

UPDATE: this is a duplicate of
Is the StaticFactory in codecampserver a well known pattern?
Edit: Please note that this answer was given before the question was completely changed over in an edit. Because of that, it now refers to things that were only present in the question as originally stated. I beg your pardon for all the "dangling pointers". :-)
Short answer:
With the code you've posted, I don't see an alternative to casting to IFoo<T>. If you don't, the compiler will give a warning (on my machine, at least).
More elaborate answer:
Does your code actually have to be that way? More specifically, do you need the cast in question in the first place?
I assume you are going to call your factory method more or less like this:
var stringFoo = FooFactory.CreateFoo<string>();
You have to provide the template parameter (string in this case) explicitly because it cannot be derived from any method argument (in this case because there aren't actually any at all). Obviously, the factory method will return an IFoo<string>.
Now, since you have to explicitly specify the type at run-time, you could just as well write:
var stringFoo = StringFoo.Create();
and therefore have a factory method inside StringFoo, like this, that unconditionally does the obvious:
public class StringFoo : IFoo<string>
{
...
public static StringFoo Create() // or alternatively, return an IFoo<string>
{
return new StringFoo();
}
}
By applying this pattern to other IFoo<T> implementations too, this will save you the if chain or switch block inside FooFactory.CreateFoo<T>, make your code easier, and get rid of the necessity to cast (which you are concerned about).
Don't get me wrong, I'm aware that factory methods supporting more than one object type are useful in some cases; but it seems in your case it causes more trouble than it's worth.
P.S.: You might find one aspect of some IoC containers interesting. They usually need to be configured, and this encompasses a process where you register concrete types (i.e. implementation classes) for abstract interfaces; for example (here using Autofac):
var builder = new ContainerBuilder();
builder.RegisterType<StringFoo>().As<IFoo<string>>();
Then later, you can request an object instance of an abstract type:
using (var container = builder.Build())
{
var stringFoo = container.Resolve<IFoo<string>>();
...
}
The Resolve method is the interesting part. You provide it with an abstract type, and using the registered types, it will return a concrete object of type StringFoo. Look into it, if it doesn't sound like overkill to you! :-)
Can you describe the problem you are solving with this mechanism? There is most likely a clearer way to approach it.
Edit
And yes, the code smells. You have left room open for any type, except you then constrain it back to a single type, and generate a run-time exception. Why have a type parameter in that case?
You could try something like this...
public static class FooFactory
{
private static readonly Dictionary<Type, Type> FooTypesLookup;
static FooFactory()
{
FooTypesLookup = (from type in typeof(FooFactory).Assembly.GetExportedTypes()
let fooInterface =
type.GetInterfaces().FirstOrDefault(
x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IFoo<>))
where fooInterface != null
let firstTypeArgument = fooInterface.GetGenericArguments().First()
select new { Type = type, TypeArgument = firstTypeArgument })
.ToDictionary(x => x.TypeArgument, x => x.Type);
}
public static IFoo<T> CreateFoo<T>()
{
var genericArgumentType = typeof(T);
Type closedFooType;
return FooTypesLookup.TryGetValue(genericArgumentType, out closedFooType)
? (IFoo<T>) Activator.CreateInstance(closedFooType)
: null;
}
}
Or better yet, introduce your favorite IoC container (Windsor, structure map, etc) and register all types that implement IFoo in there and then resolve them when needed in place of the Activator.CreateInstance call.

Categories