简体   繁体   中英

Can I call a static method that lives on a base class with a reference the the class implementing that base class (in C#)?

I'm having a hard time phrasing the question which is also making it hard for me to search for answers.

Here's a contrived scenario that mimics what I'd like to do:

void Main()
{
    Console.WriteLine(TestClassA.MyPropertyName());
    Console.WriteLine(TestClassB.MyPropertyName());
    
    var speaker = new TestSpeaker();
    speaker.Speak<TestClassA>();
    speaker.Speak<TestClassB>();
}

public class TestSpeaker {
    public void Speak<T>() where T : BaseClass<T> {
        Console.WriteLine(/* I want to call T.MyPropertyName() here */);
    }
}

public class TestClassA : BaseClass<TestClassA> {
    public string Name { get; set; }
}

public class TestClassB : BaseClass<TestClassB> {
    public string OtherPropertyName { get; set; }
    
}

public abstract class BaseClass<T> {

    public static string MyPropertyName(){
        return typeof(T).GetProperties().Single().Name;
    }
}

The Console right now would read:

Name
OtherPropertyName

I'd like to replace my commented out code so that it would read:

Name
OtherPropertyName
Name
OtherPropertyName

if you change your Writeline to

Console.WriteLine(BaseClass<T>.MyPropertyName());

you will get what you want

Why use a static function in a base class to retrieve information about a derived class? In any case, you could implement a member function to wrap the static call:

public static string MyStaticFunction() => return "whatever";

public string MyMemberFunction() => MyStaticFunction();

But in your scenario, perhaps you should simply declare an abstract property (or function) meant to return the value you're looking for and override it in derived classes:

Base:

public abstract string MyPropertyName { get; }

Derived:

public override string MyPropertyName => nameof(OtherPropertyName); // or more complex logic

And yet another possible solution would be to pass the information to the base class's constructor as a string (or property expression should you be so inclined):

Base:

public string MyPropertyName { get; init; }

public BaseClass(string propertyName)
{
    MyPropertyName = propertyName; // maybe validate that the property exists
}

Derived:

public MyTestClassB() : BaseClass(nameof(OtherPropertyName)) {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM