Alias for static member in C#? - c#

I have a static member:
namespace MyLibrary
{
public static class MyClass
{
public static string MyMember;
}
}
which I want to access like this:
using MyLibrary;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
MyMember = "Some value.";
}
}
}
How do make MyMember accessible (without MyClass.) to MyApp just by adding using MyLibrary?

C# doesn't allow you to create aliases of members, only of types. So the only way to do something like that in C# would be to create a new property which is accessible from that scope:
class Program
{
static string MyMember
{
get { return MyClass.MyMember; }
set { MyClass.MyMember = value; }
}
static void Main(string[] args)
{
MyMember = "Some value.";
}
}
It's not really an alias, but it accomplishes the syntax you're looking for.
Of course, if you're only accessing / modifying a member on MyClass, and not assigning to it, this can be simplified a bit:
class Program
{
static List<string> MyList = MyClass.MyList;
static void Main(string[] args)
{
MyList.Add("Some value.");
}
}

Related

Why use static methods in program.cs C#? [duplicate]

This question already has answers here:
When to use static methods
(24 answers)
Closed 2 years ago.
I always knew that I have to use static methods but I wonder why?
As you can see below I have to make "MigrateDatabase" Static
using System;
namespace OdeToFood
{
public class Program
{
public static void Main(string[] args)
{
MigrateDatabase();
}
private static void MigrateDatabase()
{
//.....
}
}
}
Let's just be clear, the only reason MigrateDatabase has to be static in this case is because you're calling it from a static method (Main). If instead MigrateDatabase was an instance method on a class, you could instantiate that class and call it
using System;
namespace OdeToFood
{
public class Program
{
public static void Main(string[] args)
{
var migration = new Migration();
migration.MigrateDatabase();
}
}
public class Migration
{
private void MigrateDatabase()
{
//.....
}
}
}
You could also put it as a instance method on Program if you're instantiating an instance of that class
using System;
namespace OdeToFood
{
public class Program
{
public static void Main(string[] args)
{
var program = new Program();
program.MigrateDatabase();
}
private void MigrateDatabase()
{
//.....
}
}
}

How to allow a different singleton class to be instantiated by passing different parameters into the constructor

I have a class in my project and I want to instantiate it only once by passing a specific parameter via the constructor, but when I pass different parameter it should instantiate a new one. How I can achieve this with the singleton design pattern? Or can you suggest another design pattern if it can't be achieved with a singleton?
class Program
{
static void Main()
{
SiteStructure s = SiteStructure.Instance;
}
}
public sealed class SiteStructure
{
static readonly SiteStructure _instance = new SiteStructure();
public static SiteStructure Instance
{
get
{
return _instance;
}
}
SiteStructure()
{
// Initialize.
}
}
You have to modify the way the _instance variable is initialised, making use of a function that accepts the parameter value that you want to pass in. Also, the _instance variable can no longer be readonly as it needs to be initialised inside of the new function.
[TestMethod]
public void CreateSingletonInstance()
{
SiteStructure s = SiteStructure.GetInstance("Abc123");
Debug.Print(s.Parameter); // outputs Abc123
SiteStructure s2 = SiteStructure.GetInstance("Is it really a singleton?");
Debug.Print(s2.Parameter); // outputs Is it really a singleton?
SiteStructure s3 = SiteStructure.GetInstance("Abc123");
Debug.Print(s3.Parameter); // outputs Abc123
Assert.AreNotEqual(s, s2); // Check to make sure they are different instances
Assert.AreEqual(s, s3); // Check to make sure they are the same instance
}
public sealed class SiteStructure
{
static Dictionary<string, SiteStructure> _siteStructures = new Dictionary<string, SiteStructure>();
static object _instance_Lock = new object();
public static SiteStructure GetInstance(string parameter)
{
if (!_siteStructures.ContainsKey(parameter))
{
lock (_instance_Lock)
{
if (!_siteStructures.ContainsKey(parameter))
{
_siteStructures.Add(parameter, new SiteStructure(parameter));
}
}
}
return _siteStructures[parameter];
}
private SiteStructure(string parameter)
{
// Initialize.
Parameter = parameter;
}
public string Parameter { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var g = SiteStructure.Instance(4);
}
}
public sealed class SiteStructure {
public static SiteStructure Instance()
{ return new SiteStructure();
}
public static SiteStructure Instance (int x)
{ return new SiteStructure (x);
}
SiteStructure() { }
SiteStructure(int x) { Console.WriteLine("Hello"); }
}
}

Passing variables between 2 threads in a c# console application (newbie here)

I'm wondering how I can send a variable from one thread to another in a c# console application. For example,
using System;
using System.Threading;
namespace example
{
class Program
{
static void Main(string[] args)
{
int examplevariable = Convert.ToInt32(Console.ReadLine ());
Thread t = new Thread(secondthread);
t.Start();
}
static void secondthread()
{
Console.WriteLine(+examplevariable);
}
}
}
I want to make "secondthread" recognize "examplevariable".
There is an overload to Thread.Start() that takes a parameter as object. You can pass your main thread variable to that and cast it as your variable type
using System;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int examplevariable = Convert.ToInt32(Console.ReadLine());
Thread t = new Thread(secondthread);
t.Start(examplevariable);
}
static void secondthread(object obj)
{
int examplevariable = (int) obj;
Console.WriteLine(examplevariable);
Console.Read();
}
}
}
if you want to pass multiple variable then use a model class and use property binding like below
using System;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TestModel tm = new TestModel();
tm.examplevariable1 = Convert.ToInt32(Console.ReadLine());
tm.examplevariable2 = Console.ReadLine();
Thread t = new Thread(secondthread);
t.Start(tm);
}
static void secondthread(object obj)
{
TestModel newTm = (TestModel) obj;
Console.WriteLine(newTm.examplevariable1);
Console.WriteLine(newTm.examplevariable2);
Console.Read();
}
}
class TestModel
{
public int examplevariable1 { get; set; }
public string examplevariable2 { get; set; }
}
}
Hope this will help
An easy way to do this, but might not work in all scenarios, would be to define a static variable on the class and assign the value read in from the console to the static variable. Like so:
class Program
{
static int examplevariable;
static void Main(string[] args)
{
examplevariable = Convert.ToInt32(Console.ReadLine ());
Thread t = new Thread(secondthread);
t.Start();
}
static void secondthread()
{
Console.WriteLine(+examplevariable);
}
Also, see this question on how to pass parameters to a Thread:
ThreadStart with parameters

Why can extension method not overwrite original object?

It seems that an extension method in C# cannot overwrite the original object. Why is that? Example:
using System;
namespace ExtensionTest
{
public class MyTest {
public string MyName { get; set; }
}
class Program
{
static void Main(string[] args)
{
var myTest = new MyTest() { MyName = "Arne" };
Console.WriteLine("My name is {0}", myTest.MyName);
// Will write "My name is Arne"
myTest.AlterMyTest();
Console.WriteLine("My name is {0}", myTest.MyName);
// Will write "My name is Bertil"
myTest.OverwriteMyTest();
Console.WriteLine("My name is {0}", myTest.MyName);
// Will write "My name is Bertil" (why?)
}
}
public static class ExtensionClass{
public static void AlterMyTest(this MyTest myTest)
{
myTest.MyName = "Bertil";
}
public static void OverwriteMyTest(this MyTest myTest)
{
myTest = new MyTest() { MyName = "Carl" };
}
}
}
Because as usual, reference of the class is copied while passing to the method, and you are assigning new object to the new reference.
For not-extension methods, you can pass reference by ref/out keywords
public static void Func(out MyClass b)
{
b = new MyClass();
}
...
MyClass b;
Func(out b);
Assert.IsNotNull(b);
but C# compiler doesn't allow to use ref with this(the reason is in David Arno's comment). You are free to remove this keyword, and call static method instead of extension.

Get the name of the class where the object was created

I have two classes as follow:
First one:
class Class1
{
private void Method1()
{
var obj=new TestClass();
obj.TestMethod1();
}
}
Second One:
class TestClass
{
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
//get the calling class
}
}
When Class1.Method1 calls TestClass.TestMethod1 which in turn calls TestClass.TestMethod2, I want to get the fully qualified class name of Class1 inside TestClass.TestMethod2. I have seen this link, but I think I will get TestClass.TestMethod1 as method name and TestClass as the class name. How can I get the calling class name?
There is no nice way to do that. You can access the stack-frames (just look at the second frame, rather than the first) - but that is expensive and brittle. You could use optional caller-member-name attributes (being explicit from TestMethod1) to get hold of "Method1", but not the "Class1" part. One other option would be to pass in an object (or just the name) explicitly; for example:
private void Method1()
{
var obj=new TestClass();
obj.TestMethod1(this);
}
public void TestMethod1(object caller=null,
[CallerMemberName] string callerName=null)
{
TestMethod2(caller??this,callerName??"TestMethod1");
}
private void TestMethod2(object caller=null,
[CallerMemberName] string callerName=null)
{
string callerName = ((caller??this).GetType().Name) + "." + callerName
//get the calling class
}
but I have to confess that is pretty ugly
Perhaps better would be to question why you need this in the first place.
Could you not pass the type into the second class via constructor like:
class Class1
{
private void Method1()
{
Type t = typeof(Class1);
var obj = new TestClass(t);
obj.TestMethod1();
}
}
class TestClass
{
private Type _caller;
public TestClass(Type type)
{
_caller = type;
}
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
//Do something with the class
}
}
You might check out this code to find your solution without having to pass class instances or type parameters, etc....:
class Program
{
static void Main(string[] args)
{
var c = new Class1();
c.Method1();
}
}
class Class1
{
public void Method1()
{
var obj = new TestClass();
obj.TestMethod1();
}
}
class TestClass
{
public void TestMethod1()
{
TestMethod2();
var mth = new StackTrace().GetFrame(1).GetMethod();
var clss = mth.ReflectedType.Name;
Console.WriteLine("Classname in Method1(): {0}", clss);
}
private void TestMethod2()
{
//get the calling class
var mth = new StackTrace().GetFrame(1).GetMethod();
var clss = mth.ReflectedType.Name;
Console.WriteLine("Class in .Method2(): {0}", clss);
}
}
This will get the Type that first called TestClass. It prints:
TestStack.Class1
TestStack.Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TestStack
{
class Class1
{
public void Method1()
{
var obj = new TestClass();
obj.TestMethod1();
}
}
class TestClass
{
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
StackTrace st = new StackTrace();
Type calling = null;
foreach (var sf in st.GetFrames())
{
var type = sf.GetMethod().DeclaringType;
if (type != this.GetType())
{
calling = type;
break;
}
}
Console.WriteLine(calling);
}
}
class Program
{
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Method1();
TestClass testClass = new TestClass();
testClass.TestMethod1();
}
}
}

Categories

Resources