简体   繁体   中英

C# Method in base class that returns derived type

I'm trying to create a method in a base class that would be able to return derived types. It's not necessary that it actually resides in the base class, but I would like to not have to implement the method in all derived classes.

Something like this.

public class Error
{
    protected Error() { }

    public string Message { get; protected set; }

    public static Error Because(string msg)
    {
        return new Error() { Message = msg };
    }
}

And then I create two derived types:

public class MyError : Error
public class OtherError : Error

that I'm able to instantiate with Because without any further implementation.

I know I'm able to do an implementation like this:

public static T Because<T>(string message)
    where T : Error
{
    var error = default(T);
    error.Message = message;

    return error;
}

But then I have to specify the type parameter:

MyError err = Error.Because<MyError>("My error");

or

MyError simp = MyError.Because<MyError>("My error");

I would like to be able to call it with something like this:

MyError myError = MyError.Because("Something went wrong");
OtherError myError = OtherError.Because("Something else went wrong");

Looks like a Curiously recurring template pattern fits here.

Like:

    public abstract class Error<ConcreteError>
        where ConcreteError : Error<ConcreteError>, new()
    {
        protected Error() { }

        public string Message { get; protected set; }

        public static ConcreteError Because(string msg)
        {
            return new ConcreteError() { Message = msg };
        }
    }
    public class MyError : Error<MyError> { }
    public class OtherError : Error<OtherError> { }

    static void Main(string[] args)
    {

        MyError myError = MyError.Because("Something went wrong");
        OtherError myError2 = OtherError.Because("Something else went wrong");
    }

The feature you are describing is a return type covariance which is an accepted and championed language feature which will be implemented in one of the next versions of C# language. Currently release is planned for C# 9.0.

For more details, pls have a look at the corresponding dotnet/csharplang discussion thread:

Champion "Covariant Return Types"

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