Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 约束参数,新()_C#_Oop_Generics_Inheritance_Abstract Class - Fatal编程技术网

C# 约束参数,新()

C# 约束参数,新(),c#,oop,generics,inheritance,abstract-class,C#,Oop,Generics,Inheritance,Abstract Class,有没有办法将解析方法移动到抽象类中?我尝试了多种方法(底部的链接),但我仍然遇到了一个或另一个障碍 公共类animalentyId:EntityId 提前感谢否,您不能编写模板约束,例如new(string),而只需编写new()。您必须利用反射使其工作: public abstract class EntityId<TEntityId> where TEntityId : EntityId<TEntityId> { private readonl

有没有办法将解析方法移动到抽象类中?我尝试了多种方法(底部的链接),但我仍然遇到了一个或另一个障碍

公共类animalentyId:EntityId


  • 提前感谢

    否,您不能编写模板约束,例如
    new(string)
    ,而只需编写
    new()
    。您必须利用反射使其工作:

    public abstract class EntityId<TEntityId>
        where TEntityId : EntityId<TEntityId>
    {
        private readonly System.Guid value;
    
        protected EntityId(string value)
        {
            this.value = System.Guid.Parse(value);
        }
    
        protected EntityId()
        {
            this.value = System.Guid.NewGuid();
        }
    
        public static TEntityId Parse(string value)
        {
            return (TEntityId)Activator.CreateInstance(typeof(TEntityId), new object[] { value });
        }
    }
    
    公共抽象类EntityId
    其中TEntityId:EntityId
    {
    私有只读系统。Guid值;
    受保护的EntityId(字符串值)
    {
    this.value=System.Guid.Parse(值);
    }
    受保护的EntityId()
    {
    this.value=System.Guid.NewGuid();
    }
    公共静态TEntityId解析(字符串值)
    {
    return(TEntityId)Activator.CreateInstance(typeof(TEntityId),新对象[]{value});
    }
    }
    

    假设您使构造函数可访问(而不是当前的私有构造函数)。注意约束
    where TEntityId:EntityId
    ——这将确保我们只返回
    EntityId

    的子类,如果您不介意使用反射,可以将
    Parse
    移动到抽象类型中,如下所示:

    public static TEntityId Parse(string val) {
        var constr = typeof(TEntityId).GetConstructor(
            // Since the constructor is private, you need binding flags
            BindingFlags.Instance | BindingFlags.NonPublic
        ,   null
        ,   new[]{ typeof(string) }
        ,   null);
        if (constr == null) {
            throw new InvalidOperationException("No constructor");
        }
        return (TEntityId)constr.Invoke(new object[] {val});
    }
    

    设为私有可变字段/属性,并通过
    Parse
    方法进行实际设置,如何

    (为了简单起见,从
    EntityId
    中删除了一个奇怪的重复出现的泛型参数)


    澄清一下:您正在寻找抽象类上的方法
    publicstatictentyid Parse(stringvalue){…}
    ?此方法是否是
    EntityId
    是抽象的唯一原因?因为我并没有看到它既通用又抽象的原因,至少在这个简化的例子中是这样。谢谢Rob,非常干净的解决方案。因为我不会在一个循环中创建数百个对象,在考虑了一会儿之后,我决定按照您的建议使用反射,因为这样我可以为其他使用该类库的开发人员(或几个月后的我自己)提供最容易阅读的API。拥有一个简单的AnimalEntityId.Parse(“ID”)对我来说是一个巨大的优势。我还开始添加对访问非公共构造函数的更改,并意识到,我拥有与@dasblinkenlightKirill建议的相同的代码,谢谢,这是一种非常有趣的方法。我决定在这种情况下使用反射,因为在这种情况下,我可以使API更干净:AnimalEntityId.Parse(“ID”)而不是EntityId.Parse(ID)。在您的建议中,我觉得实现细节正在泄漏,用户不应该看到这些细节。
    public class SimpleAnimalEntityId : EntityId
    {
        // Implicit parameterless constructor.
    }
    
    public class ParametrizedAnimalEntityId : EntityId
    {
        // Parametrized constructor only.
        public ParametrizedAnimalEntityId(int ignored)
        {
        }
    }
    
    public abstract class EntityId
    {
        // Simple scenario: derived type has a parameterless constructor.
        public static TEntity Parse<TEntity>(string value)
            where TEntity : EntityId, new()
        {
            Guid id = Guid.Parse(value);
    
            return new TEntity { value = id };
        }
    
        // Advanced scenario: derived type constructor needs parameters injected.
        public static TEntity Parse<TEntity>(string value, Func<TEntity> constructor)
            where TEntity : EntityId
        {
            Guid id = Guid.Parse(value);
            TEntity entity = constructor();
    
            entity.value = id;
    
            return entity;
        }
    
        private Guid value;
    
        protected EntityId()
        {
            value = Guid.NewGuid();
        }
    }
    
    string id = Guid.NewGuid().ToString();
    SimpleAnimalEntityId simple = EntityId.Parse<SimpleAnimalEntityId>(id);
    ParametrizedAnimalEntityId parametrized = EntityId.Parse(id, () => new ParametrizedAnimalEntityId(42));