I recently started learning C#, I'm programming in various languages like PHP, JavaScript, Go, Rust, Elixir, a bit of Java and Python.
I always was fascinated by C# and I decided now to give it a go.
So far so good, my process of learning a new language is by trying to replicate a variety of things from other languages, especially from PHP where I'm most strong.
TLTR: How I could implement this in C#?
<?php
declare(strict_types=1);
abstract class Foo
{
public static function className(): string
{
return static::class;
}
}
final class Bar extends Foo
{
}
echo Bar::className() . PHP_EOL;
The code above returns "Bar" instead of "Foo" because we are calling the name of the static, where static is the class that we are calling the className method from.
In C# I managed to do that:
using System;
using System.Reflection;
namespace LearningConsole
{
abstract class Foo
{
public static string ClassName()
{
return MethodBase.GetCurrentMethod().DeclaringType.Name;
}
}
class Bar : Foo
{
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Bar.ClassName());
}
}
}
But this returns the "Foo" class name instead of "Bar", is there a way to get the name of the class that invoking the ClassName method?
Thank you in advance!
EDIT: The reason I'm using a static method is that I'm trying to accomplish something similar in C# like this in PHP:
<?php
declare(strict_types=1);
interface Dummy {}
abstract class Base implements Dummy
{
public static function create(...$args): Dummy
{
$callingClass = static::class;
return new $callingClass(...$args);
}
}
final class Bar extends Base
{
protected function __construct() {}
}
final class Foo extends Base
{
protected function __construct() {}
}
$foo = Foo::create();
$bar = Bar::create();
echo get_class($foo) . PHP_EOL.
get_class($bar) . PHP_EOL;
The above will output: Foo Bar
Maybe in C# that kind of "magic" is considered bad practice, but it could be handy for various occasions.
Thanks!
EDIT 2: That C# is not working (obviously), but it is my understanding of what could be a good compromise for achieving somehow the above example:
using System;
using System.Reflection;
namespace LearningConsole
{
interface Dummy
{
}
abstract class Base : Dummy
{
public static Dummy Create(Dummy obj, params dynamic[] args)
{
var constructor = typeof(obj).GetConstructor();
constructor.invoke(null, args);
}
}
class Foo : Base
{
}
class Bar : Base
{
}
class Program
{
static void Main(string[] args)
{
var foo = Base.Create(Foo, null);
var bar = Base.Create(Bar, null);
}
}
}
Thanks!
You can achieve what you are looking for with a little help from generics. Here is an example
class Program
{
static void Main(string[] args)
{
var foo = Base.Create<Foo>();
var bar = Base.Create<Bar>();
Console.WriteLine(foo.GetType().Name);
Console.WriteLine(bar.GetType().Name);
Console.ReadKey();
}
}
public abstract class Base
{
public static T Create<T>(params object[] args) where T : Base
{
return (T)Activator.CreateInstance(typeof(T), args);
}
}
public class Bar : Base
{
}
public class Foo : Base
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With