I want to get the Lazy instance in another class the problem is that the T type is only set in the main class
the first class where the instance is is this:
public class singleton<T> where T : class, new()
{
private readonly static Lazy<T> val = new Lazy<T>(() => new T());
public static T instance { get { return val.Value; } }
public int UserID {get;set;}
}
now I have a other class for all user datas
public class User
{
public string Name()
{
return data.GetUserFromID(singleton.instance.UserID)
}
}
the singleton is not working because I need the Argument but the T is only in the main class
public class main : singleton<main>
{
public main()
{
UserID = 5;
}
}
EDIT
how do I get the ID from the singleton class inside another class like this
singleton file
public class singleton<T> where T : class, new()
{
private readonly static Lazy<T> val = new Lazy<T>(() => new T());
public static T instance { get { return val.Value; } }
public int UserID {get;set;}
private singleton() {
Datas.UserID = UserID;
}
}
another file
public class Datas {
public static int UserID {get;set;}
}
the singleton is not working because I need the Argument but the T is only in the main class
All you need do is change your code from:
public class User {
public string Name() {
return data.GetUserFromID(singleton.instance.UserID)
}
}
...to specifying the generic type argument:
public class User
{
public string Name()
{
var m = singleton<main>.instance;
Console.WriteLine($"Inside User.Name, m.UserId = {m.UserID}");
return "todo";
}
}
This is required because your client code is accessing the generic base directly. Had you encapsulated it into a factory manager or similar, clients would not need to specify the type.
Here is a little test harness
private void Run()
{
var x = singleton<main>.instance;
Console.WriteLine($"x.UserId = {x.UserID}");
var y = singleton<main>.instance;
Console.WriteLine($"y.UserId = {y.UserID}");
x.UserID++;
Console.WriteLine($"x.UserId = {x.UserID}");
Console.WriteLine($"y.UserId = {y.UserID}");
var user = new User();
Console.WriteLine($"User.Name = {user.Name()}");
var mp = MissPiggy.Instance;
}
Which produces the following results. Note how changing properies on two different variables modifies the same singleton.
There are a few problems too with how you are implementing singletons. A singleton class should have a private constructor and it should be the one managing lifetimes and not a secondary class.
e.g.
public sealed class MissPiggy
{
private static Lazy<MissPiggy> _instance = new Lazy<MissPiggy>(() => new MissPiggy());
private MissPiggy()
{
}
public static MissPiggy Instance
{
get { return _instance.Value; }
}
}
singleton<t> is a generic type - you can't refer to it without a generic type parameter.
Under the hood, it's actually generating new types.
So when you do this:
var mainSingleton = singleton<main>.instance;
It's actually creating a new type which looks like this:
public class NewGenericTypeWithWeirdName
{
private readonly static Lazy<main> val = new Lazy<main>(() => new main());
public static main instance { get { return val.Value; } }
public int UserID { get; set; }
}
...and if you declare var otherSingleton = singleton<SomethingElse>.instance; then it does the same thing - it creates another type, just like above, except T is replaced with SomethingElse.
That's why you can't do this:
singleton.instance.UserID
Because the compiler doesn't know which type you're referring to. Is it the type it generated for singleton<main>, or is it the type generated for singleton<SomethingElse>? They're actually different types, which means the static properties - including UserID, will be different for each of them.
You could do this:
return data.GetUserFromID(singleton<main>.instance.UserID);
^^^^^^
...because now you're telling it the actual type - it's singleton<main>.
Just to clarify, unless the class has a private constructor and no non-private constructors, it isn't a singleton.
You can do this:
var mainSingleton = singleton<main>.instance;
and it will always return the same instance of main.
But you can also do this:
var m1 = new singleton<main>();
var m2 = new singleton<main>();
You can create multiple instances, so it's not a singleton. To fix this, add a private constructor to singleton:
private singleton() {}
Now the constructor can only be called from within the class. That means the only way to get an instance is to call instance. Every time you do that you'll get the same instance, so now it really is a singleton.
Related
I need to determine if a member T of class T is a static member, in the constructor. I expect this will involve checking some attributes of "this", but I haven't been able to determine what to look for.
public class Thing
{
public static readonly List<Thing> ListOfStaticThings = new();
public static readonly Thing StaticThing1 = new ("StaticThing1");
public static readonly Thing StaticThing2 = new ("StaticThing2");
public static readonly Thing StaticThing3 = new ("StaticThing3");
public Thing NonStaticThing = new("NonStaticThing");
public string Name { get; set; }
private Thing(string name)
{
Name = name;
if(this.IsStatic) //how to determine if the thing being constructed is static?
{ ListOfStaticThings.Add(this);}
}
}
How do I identify if the Static attribute is applied to this?
*** UPDATED ***
In this example, both StaticThing and NonStaticThing will be constructed using the private constructor. However, only the StaticThing should be added to the ListOfStaticThings when constructed. The full implementation will have 20+ static readonly fields of the class type.
I've already verified that the ListOfStaticThings will contain the StaticThing.
The ListOfStaticThings has multiple uses. This is on the path to Enumeration Classes, with this list containing all the possible Things (such as account statuses) permitted by the class. In addition, the ListOfStaticThings can be passed to EFCore.HasData to seed the data in the table. It can also be used for data validation in unit testing because it contains all the data and is persisted in the model.
However, all those use cases are beyond the scope of this question. The piece I'm looking for is how to identify if the "this" being constructed is static so I can add it to the ListOfStaticThings. I want StaticThing1, 2 & 3 to be in the list, but not NonStaticThing.
*** Final Update ***
As pointed out by McAden's answer, this is not necessary because the non-static member of T cannot be added to class T without causing an infinite recursion overflow. Since only static members of T can be added, there is no need to determine if they are also static in the constructor.
I think you're going about it the wrong way - all static members should be initialized either in the property itself or in a static constructor, so I would do it this way:
public class Thing
{
public static readonly List<Thing> ListOfStaticThings;
public static readonly Thing StaticThing1 = new Thing("StaticThing1");
public static readonly Thing StaticThing2 = new Thing("StaticThing2");
public static readonly Thing StaticThing3 = new Thing("StaticThing3");
// public Thing NonStaticThing = new("NonStaticThing");
public string Name { get; set; }
private Thing(string name)
{
Name = name;
}
static Thing()
{
ListOfStaticThings = new List<Thing> {
StaticThing1,
StaticThing2,
StaticThing3
};
}
}
Now the instance constructor doesn't need to know if it's a "static" instance or not.
However, to be safe (meaning not rely on the order of initializers), I would also crate the static instances in the static constructor:
public class Thing
{
public static readonly List<Thing> ListOfStaticThings;
public static readonly Thing StaticThing1;
public static readonly Thing StaticThing2;
public static readonly Thing StaticThing3;
public string Name { get; set; }
private Thing(string name)
{
Name = name;
}
static Thing()
{
ListOfStaticThings = new List<Thing> {
StaticThing1 = new Thing("StaticThing1"),
StaticThing2 = new Thing("StaticThing2"),
StaticThing3 = new Thing("StaticThing3")
};
}
}
Now, if you need to know if it's "static" for some other reason, then I would create another private constructor that takes a static flag:
private Thing(string name, bool isStatic=False) : this(name)
{
if (isStatic) {
// Do different stuff for a "static" instance
}
}
but I would not put logic there to "add itself" to a static list - that can be accomplished more cleanly another way.
how [do I] prevent non-static members being added to the list
If you want to make the list immutable, then you could either expose it as an immutable type or interface like 'IEnumerable', or you could just
generate the list on the fly with a static property getter:
public static IEnumerable<Thing> ListOfStaticThings {
get {
return new List<Thing> {
StaticThing1,
StaticThing2,
StaticThing3
};
}
}
Updated Answer:
In OP's very specific preferred approach there's no point. The public Thing NonStaticThing = new("NonStaticThing"); will result in a StackOverflowException as each child will try to create another child infinitely.
In general, however, my advice to anybody trying to do something "statically" and otherwise "not" would be to use a static constructor for static things.
Original Answer based upon un-edited question:
Order of operations - The static field will be assigned before anything else outside that class can call the constructor on that class and the constructor for setting that static readonly field will be called before the static field is actually assigned. Simply check to see if the static field is null in your constructor.
private static void Main(string[] args)
{
var test = new Thing();
Console.WriteLine(test.IsStaticInstance); // False
Console.WriteLine(Thing.Instance.IsStaticInstance); // True
}
public class Thing
{
public static readonly Thing Instance = new Thing();
public Thing()
{
IsStaticInstance = Instance == null;
}
public bool IsStaticInstance { get; }
}
I have an inheritance tree with a bunch of different classes. Each of these classes has some static properties that I need acces to from time to time. Sometimes I need the property of a particular class, and sometimes I need the property of the specific class some polymorphic instance turns out to be.
This would be easy in, say, Java (I think). Just make a bunch of static fields (can these be overriden? I'm not sure). But in C#, non-static fields can ONLY be accessed via an instance (naturally), and static fields can ONLY be accessed via their corresponding class (unnaturally).
And, you can't "overload" by, er, staticity. If a class has a static and a non static Foo, doing instance.Foo fails because it is unclear to the compiler which Foo you're referring to even though it's impossible you're referring to the static one since it's disallowed.
Ok, I'll provide some code. Say I have this:
class Base
{
public static readonly string Property = "Base";
}
class Child1 : Base
{
public static readonly new string Property = "Child 1";
}
class Child2 : Base
{
public static readonly new string Property = "Child 2";
}
And then, somewhere:
public void SomeMethod(Base instance)
{
System.Console.WriteLine(instance.Property); // This doesn't work.
}
And somewhere else:
public void SomeOtherMethod()
{
System.Console.WriteLine(Child2.Property);
}
I want something like that, that actually works.
As Peter Duniho said, this can be done with reflection.
For example, these can be defined within the base class:
public const string Property = "Base";
public virtual string InstanceProperty
{
get
{
return (string)this.GetType()
.GetField("Property", BindingFlags.Public | BindingFlags.Static)
.GetValue(null);
}
}
And then each derived class just has to redefine Property using the new keyword.
I think the best you'll do in C# is something like this:
public class BaseClass
{
public virtual string InstanceProperty
{
get { return StaticProperty; }
}
public static string StaticProperty
{
get { return "BaseClass"; }
}
}
public class Derived1Base : BaseClass
{
public override string InstanceProperty
{
get { return StaticProperty; }
}
public new static string StaticProperty
{
get { return "Derived1Base"; }
}
}
public class Derived1Derived1Base : Derived1Base
{
}
public class Derived2Base : BaseClass
{
public override string InstanceProperty
{
get { return StaticProperty; }
}
public new static string StaticProperty
{
get { return "Derived2Base"; }
}
}
I have two classes that I'm trying to use to implement a string enumeration pattern. The problem is the static constructor for the child class isn't being called when an operator of the parent class is called. Is there a way I can fix that without adding a hack to the code to initialize the static members?
public abstract class BaseStringEnum<T> where T : BaseStringEnum<T>
{
public string Value { get; private set; }
private static List<T> _values = null;
protected static List<T> Values
{
get
{
if (_values == null)
{
_values = new List<T>();
}
return _values;
}
}
protected BaseStringEnum(string value, string resId)
{
Value = value;
ResourceId = resId;
Values.Add((T)this);
}
public static implicit operator string(BaseStringEnum<T> value)
{
return value.Value;
}
public static implicit operator BaseStringEnum<T>(string value)
{
return Values.Where(v => v.Value.Trim() == value.Trim()).First();
}
}
public sealed class UseTimeStringEnum : BaseStringEnum<UseTimeStringEnum>
{
private UseTimeStringEnum(string value, string resourceId) : base(value, resourceId) { }
public static readonly UseTimeStringEnum None;// = new UseTimeStringEnum("N", "None");
public static readonly UseTimeStringEnum Required;// = new UseTimeStringEnum("R", "Required");
public static readonly UseTimeStringEnum Optional;// = new UseTimeStringEnum("O", "Optional");
static UseTimeStringEnum()
{
None = new UseTimeStringEnum("N", "None");
Required = new UseTimeStringEnum("R", "Required");
Optional = new UseTimeStringEnum("O", "Optional");
}
}
The problem is when the code tries to do something like (UseTimeStringEnum)"R" it fails because the static constructor hasn't fired yet. I feel like it should fire because I'm using a static operator.
Static constructor of some class is called once one of the following conditions is met:
Instance of the class is created;
any static field of the class is accessed.
Since you do not create instances of UseTimeStringEnum neither acess it's static fields within your code, the static constructor is not called.
So the point is: BaseStringEnum does not know of UseTimeStringEnum at the compile time.
I see the only proper solution - we can refer UseTimeStringEnum at the runtime.
I added static constructor to the BaseStringEnum class wich loads and observes all available subclasses with Reflection.
now the static constructor is called.
EDIT: Mykroft pointed there is the way to call a static constructor directly instead of referencing static fields with reflection. So i believe the final code snippet should be
static BaseStringEnum()
{
var StringEnumTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(type => type.IsSubclassOf(typeof(BaseStringEnum<T>)));
foreach (var type in StringEnumTypes) type.TypeInitializer.Invoke(null, null);
}
As others rightly pointed out my constructor isn't being called because the parent class doesn't know the child class. Fortunately in this SO question I found a snippet of code that calls the constructor explicitly.
typeof(T).TypeInitializer.Invoke(null, null);
This works for my purposes here.
Is it possible to selectively chose (with a decorator maybe?) what methods are exposed to an object based on a constructor that is called?
For example my class has 2 constructors, an empty one and one that passes in a file path string.
public class MyClass
{
private readonly string _filePath;
public MyClass()
{
}
public MyClass(string filePath)
{
_filePath = filePath
}
public Export()
{
var fi = new FileInfo(_filePath);
}
}
Is it possible that when I create a new MyClass object that only if I use the constructor with the parameter to expose the Export method?
var myClass = new MyClass();
//myClass.Export() not available
var myClass = new MyClass(#"C:\");
//myClass.Export() is available
This is a sign that you should have two different types. Perhaps they both should be sub-types of a parent type (possibly abstract) or perhaps one should simply extend the other.
Then you can construct an instance of the appropriate type based on whether or not you have a string. The type with a string can have an additional method.
public class MyClass
{
public MyClass()
{
}
public void Foo()
{
//todo do stuff
}
}
public class BetterMyClass : MyClass
{
private readonly string _filePath;
public BetterMyClass(string filePath)
{
_filePath = filePath;
}
public void Export()
{
var fi = new FileInfo(_filePath);
}
}
And then your usage works just fine:
var myClass = new MyClass();
//myClass.Export(); //syntax error
var myClass2 = new BetterMyClass(#"C:\");
myClass.Export(); //works
Not directly. You could:
Create a factory method that returns an object of type IMyInterface, and then attempt to cast to the type containing the method you wish to expose. The cast will fail if the object is not the type exposing the method. Or..
Using a dynamic object. The method call will fail at runtime if the method does not exist.
This is possible, just not in the way you are showing here. You would want to create a new class that has only a default constructor and no Export method. Then create a second class that inherits from the first and have a constructor that requires the string and also exposes the Export method.
public class MyClass
{
public MyClass()
{ }
}
public class MyOtherClass : MyClass
{
private readonly string value;
public MyOtherClass(string value)
{
this.value = value;
}
public string Export() { return this.value; }
}
If you absolutely must have the selectivity, which is a silly design decision in my opinion, then you would want to go with a type that is built at runtime using code generation that either does or does not implement the method.
To my knowledge, no, this cannot be done in the way you mean. If you could, the compiler would generally have no way to know if the method in question was valid for the object in question. It would then have to check at run-time. If you called the method when not available, you would receive a runtime exception. You can throw an exception yourself based on a flag set in the constructor.
Ultimately, however, it's likely that what you really want is a subclass which has additional options. That would be a safer way to enable this type of functionality.
You could do this using the factory pattern and returning a different interface
public interface IExportInterface
{
void Export();
}
public interface INoExportInterface
{
//Other methods
}
internal class MyClass : IExportInterface, INoExportInterface
{
private readonly string _filePath;
public MyClass()
{
}
public MyClass(string filePath)
{
_filePath = filePath;
}
public void Export()
{
var fi = new FileInfo(_filePath);
}
}
public class MyClassFactory
{
public static IExportInterface GetMyClass(string filePath)
{
return new MyClass(filePath);
}
public static INoExportInterface GetMyClass()
{
return new MyClass();
}
}
I want to have a class like:
public class Forest<S, T>
{
static IList<Animal> coolGuys = new List<Animal>();
}
But I want coolGuys to be really static, which means it has to be unique through the entire lifetime of the application. And right now its not. MS discourages this pattern, ReSharper warns, but how does one really achieve what I want?
May be I will have to do more work by creating another static class and have a public static field there or a public instance field in another singleton class. Its ok to have a redundant public class to hold just a static field, but the thing I want to avoid is the field being public/internal. I mean coolGuys is just meant for Forest<,>, why expose the incoherent things to outside world.
public class Forest
{
public static IList<Animal> coolGuys = new List<Animal>(); //want to avoid
}
public class Forest<S, T>
{
Forest.coolGuys.Add(cutie);
}
Any better pattern?
Approach 1 - Inject a State Provider
Create a type to store data.
Abstract it with an interface, so you can inject a different provider if desired (e.g. for testing).
Consuming class doesn't care about the implementation, other than it guarantees statefulness.
Concurrent dictionary takes care of thread safety.
public interface IStateProvider
{
void Store( string key, object value );
object Get( string key );
}
public class StateProvider : IStateProvider
{
private static ConcurrentDictionary<string, object> _storage = new ConcurrentDictionary<string, object>();
public void Store( string key, object value )
{
// add to storage
}
public object Get( string key )
{
// get from storage
}
}
public class Forest<T1, T2>
{
private IStateProvider _stateProvider;
public Forest( IStateProvider stateProvider )
{
_stateProvider = stateProvider;
}
public void Foo()
{
// do something with the stateful value
}
}
// of course, you could do this with a DI framework
var stateProvider = new StateProvider();
var forest = new Forest<Foo, Bar>( stateProvider );
Approach 2 - Base Class
This approach is less elegant but a bit more straightforward.
public abstract class ForestBase
{
private static List<object> _staticList = new List<object>();
protected List<object> StaticList
{
get { return _staticList; }
}
}
public class Forest<T1, T2> : ForestBase
{
public void Foo()
{
StaticList.Add( 12345 );
}
}
This hides internal data and should give you only one single instance of the static list, versus one instance per combination of generic arguments.