繁体   English   中英

从抽象 class 上的方法返回子类型,或对具有不同参数类型的子强制两个构造函数

[英]Return child type from a method on an abstract class or force two constructors on child with different parameters types

我有一个抽象的 class 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 )

我想强制每个孩子 class 使用该方法或带有字符串参数的第二个构造函数,但我真的不知道如何处理它。 我知道一些像这样的“简单”答案: 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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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