I have a type that I would like to be cached, in that, since it's immutable, if you call new Foo(1), it creates it but also adds that instance to a cache, and if you do it again, you'll just end up with the cached Foo with a value of 1.
Somehow this means I need to intercept the call new <Type>(), and instead use custom logic.
Is this possible, and if so, how is its performance?
You would have to modify the compiled IL. It would be hard to implement and unreadable. Anyone who sees new expects a new instance to be created.
Better use a static factory method:
public class Foo
{
public static Foo GetInstance(int parameter)
{
if (FooCache.IsCached(parameter))
{
// return instance from cache
}
else
{
Foo instance = new Foo(parameter);
// add to cache
return instance;
}
}
private Foo(int parameter)
{
}
}
Notice that the constructor is private. The only way to get an instance of this class is to use the factory method.
The standard way to do this is to use the Factory Pattern and a private constructor. The private constructor means no code outside of the class can use new Foo(1), but instead you will write something like Foo.newFoo(1);, which will hold the logic to create a new Foo or return a cached value.
Related
I have a series of classes which initialize themselves when created based on using reflection to read a custom attribute on each property/field. The logic for all that is contained in an Initialize() method which they all call, which exists on the base class they inherit from.
I want to add usages of Lazy<T> to these classes, but I don't want to specify the function(s) in the constructor for each class, because they are "thin" constructors and the heavy lifting is in Initialize(). Conversely, I want to keep type-safety and such so I can't just provide a string of the code to use to initialize the Lazy<T>. The problem is that any usage which refers to the specific properties of the object can't be used in a static context.
Specifically, this is what I want my code to look like in an ideal world:
public class Data : Base
{
public Data(int ID) { Initalize(ID); }
[DataAttr("catId")] // This tells reflection how to initialize this field.
private int categoryID;
[LazyDataAttr((Data d) => new Category(d.categoryID))] // This would tell reflection how to create the Lazy<T> signature
private Lazy<Category> _category;
public Category Category { get { return _category.Value; } }
}
public abstract class Base
{
protected void Initalize(int ID)
{
// Use reflection to look up `ID` and populate all the fields correctly.
// This is where `categoryID` gets its initial value.
// *** This is where _category should be assigned the correct function to use ***
}
}
I would then access this the same way I would if Category were an automatic property (or an explicitly lazy loaded one with an _category == null check)
var data = new Data();
var cat = data.Category;
Is there any way I can pass the type information so that the compiler can check that new category(d.categoryID) is a valid function? It doesn't have to be via an Attribute, but it needs to be something I can see via Reflection and plug in to anything that has a Lazy<T> signature.
As an alternative, I will accept a way to do
private Lazy<Category> _category = (Data d) => new Category(d.categoryID);
This could either avoid reflection altogether, or use it to transform from this form to a form that Lazy<T> can handle.
I ended up using a solution inspired by #Servy's suggestion to get this working. The base class's Initialize() method now ends with:
protected void Initialize()
{
// Rest of code...
InitializeLazyVars();
/* We need do nothing here because instantiating the class object already set up default values. */
foreach (var fi in GetLazyFields())
{
if (fi.GetValue(this) == null)
throw new NotImplementedException("No initialization found for Lazy<T> " + fi.Name + " in class " + this.GetType());
}
}
InitializeLazyVars() is a virtual method that does nothing in the base class, but will need to be overridden in the child classes. If someone introduces a new Lazy<T> and doesn't add it to that method, we'll generate an exception any time we try to initialize the class, which means we'll catch it quickly. And there's only one place they need to be added, no matter how many constructors there are.
I currently have a class and I am a bit confused with its constructor .
public class BarListTracker : GotTickIndicator
{
public BarListTracker(BarInterval interval) : this(new BarInterval[] { interval }) { }
}
what does the statement this(new BarInterval[] { interval }) imply ?
This is constructor chaining. Essentially, you're calling a different constructor before executing the contents of that constructor.
public class Foo
{
public Foo()
: this("Hello")
{
Console.Write(" World!");
}
public Foo(string text)
{
Console.Write(text);
}
}
new Foo(); //outputs "Hello World!"
So somewhere in your BarListTracker there should be another constructor that takes either a BarInterval[] array or an IEnumerable<BarInterval> like this:
public class BarListTracker : GotTickIndicator
{
public BarListTracker(BarInterval interval)
: this(new BarInterval[] { interval })
{
//specific initialization for this constructor
}
public BarListTracker(BarInterval[] intervals)
{
//shared initialization logic for both constructors
}
}
It will execute the body BarListTracker(BarInterval[]), then execute the body of BarListTracker(BarInterval)
This is generally used to reduce code duplication. If you had some initialization code for your BarListTracker, it makes more sense to write it in one place and share that logic with your constructors rather than rewriting it for each one.
In addition, it lets you pass in or modify the input parameters with basic expressions. So in this case, in-line with calling the BarListTracker(BarInterval[]) constructor, it's wrapping the single BarInterval interval object as an array to match the signature. Likely this is just a convenience overload to provide a simpler API for programmers who may often have only a single BarInterval to construct the tracker with.
This means a call of another constructor of the BarListTracker that takes an array of BarInterval objects, passing in an array containing the object passed into this constructor. It makes the call
var tracker = new BarListTracker(interval);
equivalent to this:
var tracker = new BarListTracker(new BarInterval[] { interval });
That is indicating that they are basing, or calling, another constructor in the class when this one gets called and passing the value as an array of BarInterval. In this case it's not a base class because otherwise it would say : base(...), it's another constructor defined in this very same class.
This is very common because you want to access a class a number of different ways, and in this case, it appears they wanted to be able to send just a single object at times without setting up an array in the code.
However, one thing they could have done is just changed the other constructor, the one being called with : this to be this:
public BarListTracker(params BarInterval[] interval)
and they wouldn't have even needed the second constructor. It's a cleaner solution and yields the same results everywhere. The other constructor still gets an array, you can even pass an array to it if you wanted:
var arrOfBarInterval = new BarInterval[] { val1, val2 };
var tracker = new BarListTracker(arrOfBarInterval);
But, you can also just pass one:
var tracker = new BarListTracker(barInterval);
If you have the ability to do that I would recommend it.
One caveat to note, the : this(...) constructor gets called and executed before the constructor you're in. Keep that in mind when building logic.
Call another constructor in this class, something like this:
public BarListTracker(BarInterval[] intervals)
It calls another constructor of the same class for example
public class Point{
public Point(int x, int y){
this.x=x;
this.y=y;
}
public Point():this(0,0){}
}
if in your code you call
var p= new Point();
you will use the parameterless constructor defined which will call the constructor with parameter passing to him 0,0
this is pretty usefull if you have more than one constructor which accept a lot of parameter and want to provide simpler constructor with default parameter
you will have another constructor that takes array of BarInterval as parameter . This is basically nothing but calling a constructor from another constructor . Another link that might be helpful is Call one constructor from another
I am working with WF4 and need to use Types I created before, in a Workflow, but I'm not sure of my strategy.
I have a class:
class MyClass
{
public MyClass()
{
//Constructor Logic
}
public void Connect()
{
//Connect to a TCP/Device for example
}
public void Disconnect()
{
//Disconnect from a TCP/Device for example
}
}
and i want to use it in a WF4 Flowchart or StateMachine.
Then i have my main application:
class Program
{
private MyClass myObject;
WorkflowApplication WorkflowApplicationHoster;
static void Main(string[] args)
{
myObject = new MyClass;
IDictionary<string,object> input = new Dictionary<string,object>() {{"MyClassInstance",myObject} };
WorkflowApplicationHoster = new WorkflowApplication(new MyWorkflow,input);
WorkflowApplicationHoster.Run();
}
}
In my Workflow i have the "InArgument" -> "MyClassInstance" which is a MyClass Type and i use it for the whole workflow.
This doesn't feel correct. How to use own classe with the WF4?
OK -- so if I'm understanding this properly what you're trying to understand is how to get a new instance of your type into the workflow so it can be used. Generally speaking I've always been able to simply declare a variable and initialize it in some manner, but the question becomes what kind of initialization do you need?
If you just need to create a new instance of it, like shown above, then declare a variable of your type and in the Default Value issue the New {TypeName}() to create a new instance.
However, you're going to need to provide a lot more information if this doesn't help.
You want to use that MyClass instance in global scope; is how I read this.
One popular way is to create it as a Singleton. Generally this means you have a private/protected constructor and a public Instance method that ensures that one and only one instance is ever created.
Another way is to make the class, and thus all it's methods, static.
There are multiple threads in StackOverflow on the topic of these approaches. Additionally, it seems the real argument is whether to have something in global scope or not, not necessarily how that's implemented.
How can a static property reference a nonstatic method?
Example:
public static int UserID
{
get
{
return GetUserID();
}
}
private int GetUserID()
{
return 1;
}
When I try to compile this, I get the error: "An object reference is required for he non-static field, method or property "GetUserID()"
This doesn't work.
When you define a static property (or static method), you're defining a property that works on the class type, not on an instance of the class.
Instance properties and methods, on the other hand, work upon a specific, constructed, instance of a class. In order to use them, you need to have a reference to that specific instance. (The other way around, however, is fine.)
As an example, think of Fruit, and an "Apple" class. Say the apple class has an instance property that is how ripe the Apple is at this point in time.
You wouldn't as "Apple" to describe how ripe it is, but rather a specific "Apple" (instance). On the other hand, you could have an instance of an apple, and ask it whether it contains seeds (which might be defined on the Apple class itself (static)).
You'll just have to create a new instance:
public static int UserID
{
get
{
return new MyClass().GetUserID()
}
}
Well, you don't have to create a new instance every time UserId is called -- you can have a static field containing an instance of MyClass instead (which of course would be an approach toward implementing the Singleton pattern).
Although you can read that your static property is calling a method that could be made static, the other method isn't static. Thus, you must call the method on an instance.
You need somehow to get an instance. Without an instance, it's impossible to call an instance method.
For your case, are you sure that you need GetUserID() to be an instance method? It returns anyway the same value. Or, if your code is just dummy, and you require more logic in GetUserID(), maybe you can tell us what you intend to do?
An easy way to think about it is the following: a non-static method (or property, because properties are just wrapped-up methods) receives, as a first hidden parameter, a reference to the instance on which they operate (the "this" instance within the called method). A static method has no such instance, hence nothing to give as first hidden parameter to the non-static method.
Simply it can't.
If you need to call a static method to invoke an instance method, probably you want a Singleton
Try look at:
http://en.wikipedia.org/wiki/Singleton_pattern
Example:
public sealed class Singleton
{
private static readonly Singleton _instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return _instance;
}
}
public static int UserID
{
get
{
return _instance.GetUserID();
}
}
private int GetUserID()
{
return 1;
}
}
From the perspective of an API end-user who needs to "get an the instance" of a Singleton class, do you prefer to "get" an the .Instance property or "call" a .GetInstance() Method?
public class Bar
{
private Bar() { }
// Do you prefer a Property?
public static Bar Instance
{
get
{
return new Bar();
}
}
// or, a Method?
public static Bar GetInstance()
{
return new Bar();
}
}
In C#, I would far prefer .Instance, as it fits in with the general guidelines.
If you want to create singleton you cannot just return new object on every GetInstance call or Instance property getter. You should do something like this:
public sealed class Bar
{
private Bar() { }
// this will be initialized only once
private static Bar instance = new Bar();
// Do you prefer a Property?
public static Bar Instance
{
get
{
return instance;
}
}
// or, a Method?
public static Bar GetInstance()
{
return instance;
}
}
And it doesn't really matter which way of doing that you choose. If you prefer working with properties choose it, if you prefer methods it will be ok as well.
As with just about everything, it depends :)
If the singleton is lazy-loaded and represents more than a trivial amount of work to instantiate, then GetInstance() is more appropriate, as a method invocation indicates work is being done.
If we're simply masking to protect the singleton instance, a property is preferable.
Depends. Do you need to pass parameters? If so, I'd do GetInstance(). If not, probably doesn't matter (at least from a calling standpoint, since they're really both methods anyway; however, it does matter if you're trying to be more standards-based and, in that case, an instance appears to be better).
public class Singleton
{
private volatile static Singleton uniqueInstance;
private static readonly object padlock = new object();
private Singleton() { }
public static Singleton getInstance()
{
if (uniqueInstance == null)
{
lock (padlock)
{
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
In the above code double checking is implemented ,first it is checked if an instance is is created and if not lock has been established .Once in this block
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
if the instance is null then create it.
Also, the uniqueInstance variable is declared to be volatile to ensure that assignment to the instance variable completes before the instance variable can be accessed.
I prefer property, these are standard patterns.
As #Rex said, it depends on the semantic you want to convey.
GetInstance() does not necessarily imply a singleton instance. So, I would use GetInstance() in the case where the instance creation happens on demand, direct new is not desireable and the instance could be, but is not guaranteed to be the same. Object pools fit these criteria as well. (In fact, a singleton is a specialization of an object pool with state preservation :-))
Static Instance property on the other hand implies a singleton and preserved instance identity.
Btw, as #RaYell mentioned your sample code is not a singleton, so you shouldn't be using Instance property. You can still use the GetInstance() method in this case, as it would serve as an instance factory.