微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从抽象类上的方法返回子类型,或者在具有不同参数类型的子项上强制使用两个构造函数

如何解决从抽象类上的方法返回子类型,或者在具有不同参数类型的子项上强制使用两个构造函数

我有一个抽象类 TypedIdValueBase,它有像 UserId 或 ImageId 这样的子类。 我不知道如何,但我想要一个 Parse 方法(或第二个构造函数,它在参数中采用字符串而不是 Guid)并像这样调用它:

Guid valueG = Guid.NewGuid();

UserId userId1 = UserId.Parse(valueG ); //or new UserId(valueG )
ImageId imageId1 = ImageId.Parse(valueG ); // or new ImageId(valueG )

string valueS = "0f8fad5b-d9cb-469f-a165-70867728950e";

UserId userId2 = UserId.Parse(valueS ); //or new UserId(valueS )
ImageId imageId2 = ImageId.Parse(valueS ); // or new ImageId(valueS )

我想强制每个子类具有该方法或带有字符串参数的第二个构造函数,但我真的不知道如何处理它。 我知道一些“简单”的答案是这样的: Abstract Method That Returns an Instance of Derived Class

有人已经将我之前的问题链接到另一个答案,而没有很好地阅读我想做的事情。 在链接之前注意变量或参数的类型并将其关闭到未回答问题的答案。非常感谢。

我所拥有的最好的东西是这样的:

string value = "0f8fad5b-d9cb-469f-a165-70867728950e";
UserId userId = (UserId)UserId.Parse(value); //or new TypedIdValueBase.Parse<UserId>(value)

有没有人知道如何做这样的事情?

这是没有我尝试痕迹的代码

public abstract class TypedIdValueBase : IEquatable<TypedIdValueBase>
{
    public Guid Value { get; private set; }

    protected TypedIdValueBase(Guid value)
    {
        if (value == Guid.Empty)
        {
            throw new InvalidOperationException("Id value cannot be empty!");
        }

        Value = value;
    }
}

public class UserId : TypedIdValueBase
{
    public UserId(Guid value) : base(value)
    {
    }
}

public class ImageId : TypedIdValueBase
{
    public ImageId(Guid value) : base(value)
    {
    }
}

解决方法

美好的一天,

我找到了一种方法来获得我想要的东西,但我仍然不确定这是否是一件好事。

使用下面的代码我可以做到:

UserId userId = UserId.Parse(stringValue);
UserId userId2 = new UserId(guidValue);


public class UserId : TypedIdValueBase<UserId>
{
    public UserId(Guid value) : base(value)
    {
    }
}

public abstract class TypedIdValueBase<T> : TypedIdValueBase where T : TypedIdValueBase
{
    public static T Parse(string value)
    {
        var obj = (T)new object();
        obj.Value = Guid.Parse(value);
        return obj;
    }

    protected TypedIdValueBase(Guid value) : base(value)
    {
    }
}

public abstract class TypedIdValueBase : IEquatable<TypedIdValueBase>
{
    private Guid _value;

    public Guid Value
    {
        get => _value;
        protected internal set
        {
            CheckValue(value);
            _value = value;
        }
    }

    protected TypedIdValueBase(Guid value)
    {
        CheckValue(Value);
        Value = value;
    }

    private void CheckValue(Guid value)
    {
        if (value == Guid.Empty)
        {
            throw new InvalidOperationException("Id value cannot be empty!");
        }
    }

    public bool Equals(TypedIdValueBase other) => Value == other?.Value;

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null,obj))
        {
            return false;
        }

        return obj is TypedIdValueBase other && Equals(other);
    }

    public override int GetHashCode() => Value.GetHashCode();

    public static bool operator ==(TypedIdValueBase obj1,TypedIdValueBase obj2)
    {
        if (Equals(obj1,null))
        {
            if (Equals(obj2,null))
            {
                return true;
            }

            return false;
        }

        return obj1.Equals(obj2);
    }

    public static bool operator !=(TypedIdValueBase x,TypedIdValueBase y) => !(x == y);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。