I came across this answer by Marc Gravell on how to create an object without calling its constructor. Can someone confirm this will not circumvent even the complete and best implementation of singleton pattern(Reference implementations here. And why? I guess more specifically I am not clear on the inner workings of GetSafeUninitializedObject() in the context of a Class's constructors (static, private etc)
Within the singleton pattern you have a static variable on your type that will be initialized by the type constructor.
By calling GetSafeUninitializedObject you only avoid the instance constructor which will be called after the type constructor.
Example:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private static string _StaticMessage = "Type ctor;";
private string _Message = "init; ";
static Singleton()
{ }
private Singleton()
{
_Message += "ctor; ";
}
public static Singleton Instance
{
get { return instance; }
}
public string Message { get { return _StaticMessage + _Message; } }
}
internal class Program
{
private static void Main(string[] args)
{
var singleton = Singleton.Instance;
// writes "Type ctor;init; ctor;"
Console.WriteLine(singleton.Message);
var instance = (Singleton)System.Runtime.Serialization.FormatterServices
.GetSafeUninitializedObject(typeof(Singleton));
// writes "Type ctor;"
Console.WriteLine(instance.Message);
}
}
Update to clarify difference between type initializer and static ctor asked from IllidanS4
This doesn't really belong to the answer above, but to the question within the comments: And a answer simply doesn't fit into a simple comment.
#IllidanS4: The type initializer is just a shortcut for writing an implicit static constructor. If you create a class that contains both initialization methods and decompile the resulting assembly you can see only one static constructor (.cctor) that will initialize all the variables. The both assignments will be merged where the type initializer will be called first and the statements within the static constructor last.
Take this sample class:
internal static class C
{
public static readonly string ByTypeCtor;
public static readonly string ByTypeInitializer = "From type init; ";
public static string ByBoth = "From type init; ";
static C()
{
ByTypeCtor = "From static ctor; ";
ByBoth += "From static ctor";
}
}
If you compile it and afterwards decompile it (e.g. by using ILSpy) you'll get the following code back:
internal static class C
{
public static readonly string ByTypeCtor;
public static readonly string ByTypeInitializer;
public static string ByBoth;
static C()
{
C.ByTypeInitializer = "From type init; ";
C.ByBoth = "From type init; ";
C.ByTypeCtor = "From static ctor; ";
C.ByBoth += "From static ctor";
}
}
Due to this fact i normally never use to initialize a variable directly when it will be declared. Instead i always leave them uninitialized (like the ByTypeCtor variable) and make all initializations within the constructor. This simply avoids cluttering variable initialization to different positions within the class which improves maintainability.
As everyone has mentioned, it can circumvent and undermine your design pattern.
But take a look at the recommended usage for GetSafeUninitializedObject
According to MSDN:
GetSafeUninitializedObject should only be used for deserialization when the user intends to immediately populate all fields. It does not create an uninitialized string, since creating an empty instance of an immutable type serves no purpose.
The GetSafeUninitializedObject method works even on objects with private constructors, so it could potentially be used to circumvent the singleton pattern.
Yes, the default Singleton pattern is definitely better in most situations. The expected behaviour of your type, is that it's ctor has to be called.
Creating an object without calling ctor method on that type, is not something "normal", so I, personally, would always avoid using this solution till have really strong reasons to do so.
Side note: the singleton pattern is just a pattern and not framework behaviour. In my opinion, in this question, you mix 2 concepts that don't mix together.
The first case is a way to create an object, the second case, is a way to architect code.
General rule is: don't do "strange things" (GetSafeUninitializedObject is strange one), till you really need do so. Keep goinig on common shared across all developers patterns and keep things simple as much as it possible.
Related
I am getting into C# and I am having this issue:
namespace MyDataLayer
{
namespace Section1
{
public class MyClass
{
public class MyItem
{
public static string Property1{ get; set; }
}
public static MyItem GetItem()
{
MyItem theItem = new MyItem();
theItem.Property1 = "MyValue";
return theItem;
}
}
}
}
I have this code on a UserControl:
using MyDataLayer.Section1;
public class MyClass
{
protected void MyMethod
{
MyClass.MyItem oItem = new MyClass.MyItem();
oItem = MyClass.GetItem();
someLiteral.Text = oItem.Property1;
}
}
Everything works fine, except when I go to access Property1. The intellisense only gives me "Equals, GetHashCode, GetType, and ToString" as options. When I mouse over the oItem.Property1, Visual Studio gives me this explanation:
MemberMyDataLayer.Section1.MyClass.MyItem.Property1.getcannot be accessed with an instance reference, qualify it with a type name instead
I am unsure of what this means, I did some googling but wasn't able to figure it out.
In C#, unlike VB.NET and Java, you can't access static members with instance syntax. You should do:
MyClass.MyItem.Property1
to refer to that property or remove the static modifier from Property1 (which is what you probably want to do). For a conceptual idea about what static is, see my other answer.
You can only access static members using the name of the type.
Therefore, you need to either write,
MyClass.MyItem.Property1
Or (this is probably what you need to do) make Property1 an instance property by removing the static keyword from its definition.
Static properties are shared between all instances of their class, so that they only have one value. The way it's defined now, there is no point in making any instances of your MyItem class.
I had the same issue - although a few years later, some may find a few pointers helpful:
Do not use ‘static’ gratuitously!
Understand what ‘static’ implies in terms of both run-time and compile time semantics (behavior) and syntax.
A static entity will be automatically constructed some time before
its first use.
A static entity has one storage location allocated, and that is
shared by all who access that entity.
A static entity can only be accessed through its type name, not
through an instance of that type.
A static method does not have an implicit ‘this’ argument, as does an
instance method. (And therefore a static method has less execution
overhead – one reason to use them.)
Think about thread safety when using static entities.
Some details on static in MSDN:
Static Classes in C#
Static Constructors in C#
This causes the error:
MyClass aCoolObj = new MyClass();
aCoolObj.MyCoolStaticMethod();
This is the fix:
MyClass.MyCoolStaticMethod();
Explanation:
You can't call a static method from an instance of an object. The whole point of static methods is to not be tied to instances of objects, but instead to persist through all instances of that object, and/or to be used without any instances of the object.
No need to use static in this case as thoroughly explained. You might as well initialise your property without GetItem() method, example of both below:
namespace MyNamespace
{
using System;
public class MyType
{
public string MyProperty { get; set; } = new string();
public static string MyStatic { get; set; } = "I'm static";
}
}
Consuming:
using MyType;
public class Somewhere
{
public void Consuming(){
// through instance of your type
var myObject = new MyType();
var alpha = myObject.MyProperty;
// through your type
var beta = MyType.MyStatic;
}
}
cannot be accessed with an instance reference
It means you're calling a STATIC method and passing it an instance. The easiest solution is to remove Static, eg:
public static void ExportToExcel(IEnumerable data, string sheetName)
{
Remove the static in the function you are trying to call. This fixed the problem for me.
I got here googling for C# compiler error CS0176, through (duplicate) question Static member instance reference issue.
In my case, the error happened because I had a static method and an extension method with the same name. For that, see Static method and extension method with same name.
[May be this should have been a comment. Sorry that I don't have enough reputation yet.]
I know this is an old thread, but I just spent 3 hours trying to figure out what my issue was. I ordinarily know what this error means, but you can run into this in a more subtle way as well. My issue was my client class (the one calling a static method from an instance class) had a property of a different type but named the same as the static method. The error reported by the compiler was the same as reported here, but the issue was basically name collision.
For anyone else getting this error and none of the above helps, try fully qualifying your instance class with the namespace name. ..() so the compiler can see the exact name you mean.
Check whether your code contains a namespace which the right most part matches your static class name.
Given the a static Bar class, defined on namespace Foo, implementing a method Jump or a property, chances are you are receiving compiler error because there is also another namespace ending on Bar. Yep, fishi stuff ;-)
If that's so, it means your using a Using Bar; and a Bar.Jump() call, therefore one of the following solutions should fit your needs:
Fully qualify static class name with according namepace, which result on Foo.Bar.Jump() declaration. You will also need to remove Using Bar; statement
Rename namespace Bar by a diffente name.
In my case, the foollowing compiler error occurred on a EF (Entity Framework) repository project on an Database.SetInitializer() call:
Member 'Database.SetInitializer<MyDatabaseContext>(IDatabaseInitializer<MyDatabaseContext>)' cannot be accessed with an instance reference; qualify it with a type name instead MyProject.ORM
This error arouse when I added a MyProject.ORM.Database namespace, which sufix (Database), as you might noticed, matches Database.SetInitializer class name.
In this, since I have no control on EF's Database static class and I would also like to preserve my custom namespace, I decided fully qualify EF's Database static class with its namepace System.Data.Entity, which resulted on using the following command, which compilation succeed:
System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(MyMigrationStrategy)
Hope it helps
YourClassName.YourStaticFieldName
For your static field would look like:
public class StaticExample
{
public static double Pi = 3.14;
}
From another class, you can access the staic field as follows:
class Program
{
static void Main(string[] args)
{
double radius = 6;
double areaOfCircle = 0;
areaOfCircle = StaticExample.Pi * radius * radius;
Console.WriteLine("Area = "+areaOfCircle);
Console.ReadKey();
}
}
First, a general note, what Xamarin calls their "linker" is actually more of a "dead code remover". It is supposed to prevent uncallable code from making it into the compiled app.
I have a type in my app. When I use reflection to get its constructors, I see zero constructors:
private static int GetConstructorCount(Type type) {
ConstructorInfo[] constructors = type.GetConstructors();
return constructors.Count();
}
Yet when I use reflection to see its instance members, I see many:
private static void LogMemberInfo(Type type) {
int constructorCount = GetConstructorCount(type);
MyLoggingMethod(constructorCount, "Constructors");
MemberInfo[] members = type.GetMembers();
List<string> willLog = new List<string>();
foreach(MemberInfo member in members) {
if (member.DeclaringType == type) {
willLog.Add(member.Name);
}
}
willLog.Sort();
foreach (string str in willLog) {
MyLoggingMethod.LogLine(str);
}
}
Output from the above is:
0 Constructors
lots of surviving members, including instance members
This is a problem, because the type is a gateway to a whole lot of other types. I was hoping that by getting rid of all the constructors, all the instance members would disappear. They don't.
Is this a bug in the linker? Or is there a reason why it might still not want to get rid of instance members?
I do access members of the type via casting. Perhaps this is the problem?
public class MySuperclass {
public static MySuperclass Instance {get; set;}
}
public MyClass: MySuperclass {
public static SomeMethod() {
MySuperclass object = MySuperclass.Instance;
MyClass castObject = object as MyClass; // castObject will always be null, as no constructors survived the linking process. But maybe the linker doesn't realize that?
if (castObject!=null) {
castObject.InstanceMethod();
}
}
}
UPDATE: Getting rid of all the casts did not solve the problem. I am calling virtual members of superclass objects in lots of places; that's my next guess, but if that's the problem, fixing will be messy.
At least in my case, calling any static method on a type leads to preservation of lots of instance members. I literally tried this:
public class MyType() {
public static bool DummyBool() {
return true;
}
// instance members here
}
Once the type was getting removed by the linker, I put in a call to MyType.DummyBool(). This led to a lot of instance members being preserved.
This may not be the case for everyone. But it was the case for me.
Another insidious thing to watch out for is that if a static class has any properties that are initialized on startup, and the class as a whole is preserved, then those properties are preserved, even if they are never called:
public static class StaticClass {
public static Foo FooProperty {get;} = new Foo(); // if any code that is not removed calls StaticClass.SomeString, then Foo will be preserved.
public static string SomeString {
get {
return "Hello";
}
}
}
I am also seeing at least one case where code in a class that is removed by the linker nonetheless causes another class not to be removed. I assume this is a bug; however, my example is rather involved, and my attempts to get a simple repro have failed.
Have you tried using the Preserve attribute? The linker will not "optimize" code decorated with it:
[Xamarin.iOS.Foundation.Preserve]
For more information see the Xamarin documentation here
I have been reviewing some code of some old projects and I found a singleton there. It is a requirement to use a singleton and I was thinking of a way to make it look "simpler" when using.
I found, it would be easier to access the methods and properties like a static class. So I basically implemented a singleton using static methods to skip the requirement to use GetInstance(). This is how I implemented it:
public class ExampleSingleton
{
string someRequiredValue = "This is an example.";
/// <summary>
/// Private Constructor
/// </summary>
private ExampleSingleton() { }
private static volatile ExampleSingletoninstance;
/// <summary>
/// !!! PRIVATE !!!
/// Instance Property.
/// Returns the instance of this singleton.
/// (ThreadSafe)
/// </summary>
private static ExampleSingleton Instance
{
get
{
if (instance == null)
{
lock (_lock)
{
if (instance == null)
{
instance = new ExampleSingleton();
}
}
}
return instance;
}
}
/// <summary>
/// Example field contains a value that should be
/// accessible from outside.
/// </summary>
public static string SomeRequiredField
{
get
{
// Here you do the job you would have to do "outside"
// of the class normally.
return ExampleSingleton.Instance.someRequiredValue;
}
}
// Helper for a secure thread synchronisation.
private static object _lock = new object();
}
So when you want to access the singleton values you can just do it like this:
// Access the values like this
string requiredField = ExampleSingleton.SomeRequiredField;
// Instead of this
string requiredField = ExampleSingleton.Instance.SomeRequiredField;
// Or even this
string requiredField = ExampleSingleton.GetInstance().SomeRequiredField;
Am I violating the principles of the singleton pattern here? It basically is still a singleton pattern but the work of getting the instance is done internally. What could be the con's of this example? Are there other pro's?
Thanks
In terms of cons, there are two that have bitten me in the past:
It's hard to mock the singleton due to the fact that the getters are static
Changes to the singleton interface need 2 separate changes (one for the public static, one for the internals).
Namely, I think that this:
ExampleSingleton.Instance.SomeRequiredField
Is easier to mock simply because you would need to replace/revert the Instance field. Questions pop up from time to time around "how to mock static this or that" probably due to classes like the one you posted:
How to mock with static methods?
Mocking Static methods using Rhino.Mocks
In general, a singleton pattern in C# is probably not the best idea due to the fact that they are harder to mock in general, unless you make the constructor public or use a ioc container, but if you need one, having the instance getter is probably easier to test in general.
Second point is more around incremental maintenance cost of code. Basically to "add to the class" you have two points of code that must be changed:
class ExampleSingleton
{
... existing code ...
public static int ComputeComplicatedMethod()
{
return ComputeComplicatedMethodImplementation();
}
private int ComputeComplicatedMethodImplementation()
{
// really complex code.
}
}
So you've essentially added an extra layer of abstraction for every new field versus just once for a get instance field. Either that or you have a static method that uses the internal static singleton like so:
class ExampleSingleton
{
... existing code ...
public static int ComputeComplicatedMethod()
{
// use ExampleSingletonInstance here
}
}
Which is really no better than just having a static class with static methods. A better question is why isn't the Singleton pattern implemented with just a static class? That might be better explained here: http://www.dotnetperls.com/singleton-static
I think you have to choose the solution with the least code (but it looks like people likes to wrote a bunch of useless code, so you may have difficulty to explain what is your point).
Use a static access to a property like in your example save you a word:
string requiredField = ExampleSingleton.SomeRequiredStuff;
vs
string requiredField = ExampleSingleton.Instance.SomeRequiredStuff;
But you have to wrote the getter for this property.
Also if you have a lot of properties it became an issue: you have to wrote a lot of static getter.
And this is not standard and go against OOP spirit: you handle the property of an object, so get the object then the property.
Also if your value is invariable, it is not a property!, the habit is to put the field const and public. Like ulong.MaxValue.
Doing this for the methods look like a bad idea. (and again in OOP, method belong to objects). If you don't want to have anything static you will have to build static functions that call the non-static ones. It will be not pleasant to maintain.
I'm implementing a singleton pattern, and need the initialization to be thread safe.
I've seen several ways to do it, like using the double check lock implementation, or other techniques (i.e.: http://csharpindepth.com/articles/general/singleton.aspx)
I wanted to know if the following approach, which is similar to the fourth version in the article, is thread safe. I'm basically calling a method in the static field initializer, which creates the instance. I don't care about the lazyness. Thanks!
public static class SharedTracerMock
{
private static Mock<ITracer> tracerMock = CreateTracerMock();
private static Mock<ITracer> CreateTracerMock()
{
tracerMock = new Mock<ITracer>();
return tracerMock;
}
public static Mock<ITracer> TracerMock
{
get
{
return tracerMock;
}
}
}
Yes, that's thread-safe - although it's not the normal singleton pattern, as there are no instances of your class itself. It's more of a "single-value factory pattern". The class will be initialized exactly once (assuming nothing calls the type initializer with reflection) and while it's being initialized in one thread, any other thread requesting TracerMock will have to wait.
Your code can also be simplified by removing the method though:
public static class SharedTracerMock
{
private static readonly Mock<ITracer> tracerMock = new Mock<ITracer>();
public static Mock<ITracer> TracerMock { get { return tracerMock; } }
}
Note that I've made the field readonly as well, which helps in terms of clarity. I generally stick trivial getters all on one line like this too, to avoid the bulk of lots of lines with just braces on (7 lines of code for one return statement feels like overkill).
In C# 6, this can be simplified even more using a readonly automatically implemented property:
public static class SharedTracerMock
{
public static Mock<ITracer> TracerMock { get; } = new Mock<ITracer>();
}
Of course, just because this property is thread-safe doesn't mean that the object it returns a reference to will be thread-safe... without knowing about Mock<T>, we can't really tell that.
I am getting into C# and I am having this issue:
namespace MyDataLayer
{
namespace Section1
{
public class MyClass
{
public class MyItem
{
public static string Property1{ get; set; }
}
public static MyItem GetItem()
{
MyItem theItem = new MyItem();
theItem.Property1 = "MyValue";
return theItem;
}
}
}
}
I have this code on a UserControl:
using MyDataLayer.Section1;
public class MyClass
{
protected void MyMethod
{
MyClass.MyItem oItem = new MyClass.MyItem();
oItem = MyClass.GetItem();
someLiteral.Text = oItem.Property1;
}
}
Everything works fine, except when I go to access Property1. The intellisense only gives me "Equals, GetHashCode, GetType, and ToString" as options. When I mouse over the oItem.Property1, Visual Studio gives me this explanation:
MemberMyDataLayer.Section1.MyClass.MyItem.Property1.getcannot be accessed with an instance reference, qualify it with a type name instead
I am unsure of what this means, I did some googling but wasn't able to figure it out.
In C#, unlike VB.NET and Java, you can't access static members with instance syntax. You should do:
MyClass.MyItem.Property1
to refer to that property or remove the static modifier from Property1 (which is what you probably want to do). For a conceptual idea about what static is, see my other answer.
You can only access static members using the name of the type.
Therefore, you need to either write,
MyClass.MyItem.Property1
Or (this is probably what you need to do) make Property1 an instance property by removing the static keyword from its definition.
Static properties are shared between all instances of their class, so that they only have one value. The way it's defined now, there is no point in making any instances of your MyItem class.
I had the same issue - although a few years later, some may find a few pointers helpful:
Do not use ‘static’ gratuitously!
Understand what ‘static’ implies in terms of both run-time and compile time semantics (behavior) and syntax.
A static entity will be automatically constructed some time before
its first use.
A static entity has one storage location allocated, and that is
shared by all who access that entity.
A static entity can only be accessed through its type name, not
through an instance of that type.
A static method does not have an implicit ‘this’ argument, as does an
instance method. (And therefore a static method has less execution
overhead – one reason to use them.)
Think about thread safety when using static entities.
Some details on static in MSDN:
Static Classes in C#
Static Constructors in C#
This causes the error:
MyClass aCoolObj = new MyClass();
aCoolObj.MyCoolStaticMethod();
This is the fix:
MyClass.MyCoolStaticMethod();
Explanation:
You can't call a static method from an instance of an object. The whole point of static methods is to not be tied to instances of objects, but instead to persist through all instances of that object, and/or to be used without any instances of the object.
No need to use static in this case as thoroughly explained. You might as well initialise your property without GetItem() method, example of both below:
namespace MyNamespace
{
using System;
public class MyType
{
public string MyProperty { get; set; } = new string();
public static string MyStatic { get; set; } = "I'm static";
}
}
Consuming:
using MyType;
public class Somewhere
{
public void Consuming(){
// through instance of your type
var myObject = new MyType();
var alpha = myObject.MyProperty;
// through your type
var beta = MyType.MyStatic;
}
}
cannot be accessed with an instance reference
It means you're calling a STATIC method and passing it an instance. The easiest solution is to remove Static, eg:
public static void ExportToExcel(IEnumerable data, string sheetName)
{
Remove the static in the function you are trying to call. This fixed the problem for me.
I got here googling for C# compiler error CS0176, through (duplicate) question Static member instance reference issue.
In my case, the error happened because I had a static method and an extension method with the same name. For that, see Static method and extension method with same name.
[May be this should have been a comment. Sorry that I don't have enough reputation yet.]
I know this is an old thread, but I just spent 3 hours trying to figure out what my issue was. I ordinarily know what this error means, but you can run into this in a more subtle way as well. My issue was my client class (the one calling a static method from an instance class) had a property of a different type but named the same as the static method. The error reported by the compiler was the same as reported here, but the issue was basically name collision.
For anyone else getting this error and none of the above helps, try fully qualifying your instance class with the namespace name. ..() so the compiler can see the exact name you mean.
Check whether your code contains a namespace which the right most part matches your static class name.
Given the a static Bar class, defined on namespace Foo, implementing a method Jump or a property, chances are you are receiving compiler error because there is also another namespace ending on Bar. Yep, fishi stuff ;-)
If that's so, it means your using a Using Bar; and a Bar.Jump() call, therefore one of the following solutions should fit your needs:
Fully qualify static class name with according namepace, which result on Foo.Bar.Jump() declaration. You will also need to remove Using Bar; statement
Rename namespace Bar by a diffente name.
In my case, the foollowing compiler error occurred on a EF (Entity Framework) repository project on an Database.SetInitializer() call:
Member 'Database.SetInitializer<MyDatabaseContext>(IDatabaseInitializer<MyDatabaseContext>)' cannot be accessed with an instance reference; qualify it with a type name instead MyProject.ORM
This error arouse when I added a MyProject.ORM.Database namespace, which sufix (Database), as you might noticed, matches Database.SetInitializer class name.
In this, since I have no control on EF's Database static class and I would also like to preserve my custom namespace, I decided fully qualify EF's Database static class with its namepace System.Data.Entity, which resulted on using the following command, which compilation succeed:
System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(MyMigrationStrategy)
Hope it helps
YourClassName.YourStaticFieldName
For your static field would look like:
public class StaticExample
{
public static double Pi = 3.14;
}
From another class, you can access the staic field as follows:
class Program
{
static void Main(string[] args)
{
double radius = 6;
double areaOfCircle = 0;
areaOfCircle = StaticExample.Pi * radius * radius;
Console.WriteLine("Area = "+areaOfCircle);
Console.ReadKey();
}
}