Nice programing

인터페이스의 하위 클래스가 ToString을 구현하도록 강제

nicepro 2020. 12. 11. 19:24
반응형

인터페이스의 하위 클래스가 ToString을 구현하도록 강제


인터페이스가 IFoo있고의 모든 하위 클래스가 IFooObject의 ToString메서드 를 재정의 하고 싶다고 가정 해 보겠습니다 . 이것이 가능한가?

단순히 메서드 서명을 IFoo에 추가하는 것은 작동하지 않습니다.

interface IFoo
{
    String ToString();
}

모든 하위 클래스가 확장 Object되고 그러한 방식으로 구현을 제공하기 때문에 컴파일러는 이에 대해 불평하지 않습니다. 어떤 제안?


나는 당신이 인터페이스로 그것을 할 수 있다고 믿지 않습니다. 그래도 추상 기본 클래스를 사용할 수 있습니다.

public abstract class Base
{
    public abstract override string ToString(); 
}

abstract class Foo
{
    public override abstract string ToString();
}

class Bar : Foo
{
    // need to override ToString()
}

Jon & Andrew : 그 추상적 인 트릭은 정말 유용합니다. 추상으로 선언하여 체인을 끝낼 수 있을지 몰랐습니다. 건배 :)

과거에는 파생 클래스에서 ToString ()을 재정의해야했을 때 항상 다음과 같은 패턴을 사용했습니다.

public abstract class BaseClass
{
    public abstract string ToStringImpl();

    public override string ToString()
    {
        return ToStringImpl();
    }    
}

인터페이스 메서드를 구현하면 메서드가 암시 적으로 봉인되고 재정의됩니다. 따라서 달리 지정하지 않는 한 인터페이스의 첫 번째 구현은 C #에서 재정의 체인을 종료합니다.

필수 .NET

초록 클래스 = 당신의 친구

이 질문 확인


나는 이것이 당신의 질문에 대답하지 않는다는 것을 알고 있지만 당신이 요구하는 것을 할 방법이 없기 때문에 나는 다른 사람들이 볼 수 있도록 나만의 접근 방식을 공유 할 것이라고 생각했습니다.

저는 Mark와 Andrew가 제안한 솔루션의 하이브리드를 사용합니다.

내 응용 프로그램에서 모든 도메인 엔티티는 추상 기본 클래스에서 파생됩니다.

public abstract class Entity
{
    /// <summary>
    /// Returns a <see cref="System.String"/> that represents this instance.
    /// </summary>
    public override string ToString()
    {
        return this is IHasDescription
                   ? ((IHasDescription) this).EntityDescription
                   : base.ToString();
    }
}

인터페이스 자체는 간단한 접근 자만 정의합니다.

public interface IHasDescription : IEntity
{
    /// <summary>
    /// Creates a description (in english) of the Entity.
    /// </summary>
    string EntityDescription { get; }
}

이제 기본 제공되는 대체 메커니즘이 있습니다. 즉, Entity구현하는 IHasDescription은를 제공해야 EntityDescription하지만 Entity여전히 문자열로 변환 할 수 있습니다.

I know this isn't radically different from the other solutions proposed here, but I like the idea of minimizing the responsibility of the base Entity type, so that implementing the description-interface remains optional, but you're forced to actually implement the description-method if you're implementing the interface.

IMHO, interfaces that are implemented by the object base-class should not "count" as implemented - it would be nice to have a compiler option for that, but, oh well...


I don't think you can force any sub-class to override any of the base-class's virtual methods unless those methods are abstract.


Sorry to bury out this old thread from the grave, specially as our dear @jon-skeet already provided his own answer.

But if you want to keep the interface and not use an abstract class, I guess this is still possible by simply having your interface implementing the System.IFormattable interface.

interface IFoo : IFormattable
{
}

The only thing to keep in mind is, to properly implement this IFormattable, the concrete implementation should overwrite the Object.ToString() as well.

This is clearly explained in this nice post.

Your concrete class is now like

public class Bar : IFoo
{
    public string ToString(string format, IFormatProvider formatProvider)
    {
        return $"{nameof(Bar)}";
    }

    public override string ToString()
    {
        return ToString(null, System.Globalization.CultureInfo.CurrentCulture);
    }
}

Hope this might still help anyone.

참고URL : https://stackoverflow.com/questions/510341/force-subclasses-of-an-interface-to-implement-tostring

반응형