Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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#_Generics - Fatal编程技术网

C# 转换为使用泛型

C# 转换为使用泛型,c#,generics,C#,Generics,我已经试过好几次了,我总是让自己陷入困境。如何将此代码更改为基于泛型的方法?此代码遵循“四人帮”组合模式 public abstract class AdjacencyTreeBase { public AdjacencyTreeBase(int entityId, int entityTypeId) { EntityId = entityId; EntityTypeId = entityTypeId; } public long

我已经试过好几次了,我总是让自己陷入困境。如何将此代码更改为基于泛型的方法?此代码遵循“四人帮”组合模式

public abstract class AdjacencyTreeBase
{
    public AdjacencyTreeBase(int entityId, int entityTypeId)
    {
        EntityId = entityId;
        EntityTypeId = entityTypeId;
    }

    public long? Id { get; set; }
    public int? SystemId { get; set; }
    public int EntityId { get; set; }
    public int EntityTypeId { get; set; }
    public bool? isActive { get; set; }
    public long? lft { get; set; }
    public long? rgt { get; set; }

    public abstract void AddChild(AdjacencyTreeBase c);
    public abstract void RemoveChild(AdjacencyTreeBase c);
    public abstract List<AdjacencyTreeBase> ListChildren();
    public abstract void AddChildren(List<AdjacencyTreeBase> c);
    public abstract void ReplaceChildren(List<AdjacencyTreeBase> c);
}



实例化此对象映射的示例:

public List<AdjacencyTreeBase> CreateSample()
{
    // build bottom of tree objects...
    var client1 = new AdjacencyClient(1, 4)
    {
        first_name = "Pic'nic",
        last_name = "Basket #1",
        ssn = "123-45-6789"
    };
    var client2 = new AdjacencyClient(2, 4)
    {
        first_name = "Pic'nic",
        last_name = "Basket #2",
        ssn = "234-56-7890"
    };
    var client3 = new AdjacencyClient(3, 4)
    {
        first_name = "Bear",
        last_name = "Cave",
        ssn = "345-67-8901"
    };
    var client4 = new AdjacencyClient(4, 4)
    {
        first_name = "Picnic",
        last_name = "Table",
        ssn = "456-78-9012"
    };

    // build the next level up and add the children...
    var officer1 = new AdjacencyUser(1, 3)
    {
        first_name = "Yogi",
        last_name = "Bear",
        officer_number = "YB123"
    };
    officer1.AddChild(client1);
    officer1.AddChild(client2);

    var officer2 = new AdjacencyUser(2, 3)
    {
        first_name = "Park",
        last_name = "Ranger",
        officer_number = "PR123"
    };
    officer2.AddChild(client3);
    officer2.AddChild(client4);

    // build the top of the tree and add the middle children...
    var agencyThatAlreadyExists = new AdjacencyAgency(1, 2)
    {
        agency_name = "Jellystone",
        agency_type = "Park",
    };
    agencyThatAlreadyExists.AddChild(officer1);
    agencyThatAlreadyExists.AddChild(officer2);

    return agencyThatAlreadyExists;
}
public List CreateSample()
{
//构建树的底部对象。。。
var client1=新的邻接客户机(1,4)
{
first_name=“Pic'nic”,
last_name=“Basket#1”,
ssn=“123-45-6789”
};
var client2=新的邻接客户端(2,4)
{
first_name=“Pic'nic”,
last_name=“Basket#2”,
ssn=“234-56-7890”
};
var client3=新的邻接客户端(3,4)
{
first_name=“熊”,
last_name=“Cave”,
ssn=“345-67-8901”
};
var client4=新的邻接客户端(4,4)
{
first_name=“野餐”,
last_name=“Table”,
ssn=“456-78-9012”
};
//构建下一个级别并添加子级。。。
var officer1=新的邻接用户(1,3)
{
first_name=“Yogi”,
last_name=“熊”,
官员编号=“YB123”
};
官员1.AddChild(客户1);
官员1.AddChild(客户2);
var officer2=新的邻接用户(2,3)
{
first_name=“公园”,
last_name=“Ranger”,
官员编号=“PR123”
};
官员2.AddChild(客户3);
职员2.AddChild(客户4);
//构建树的顶部并添加中间的子级。。。
var AgencyThathareadyExists=新邻接(1,2)
{
机构名称=“水母”,
机构类型=“公园”,
};
已存在的代理。AddChild(办公室1);
已存在的代理。添加儿童(2号官员);
已经存在的退货代理;
}
虽然我的示例非常简单,但我们的实体结构并不是那么简单。我们目前有7个不同的实体,几乎任何类型的实体都可以是任何类型实体的子实体,其兄弟实体也可以是各种类型

短暂性脑缺血发作

编辑:
试图澄清:子对象(以及子对象的子对象)可以是任何实体类型(代理、用户、官员、客户等)。虽然所有实体都有共同的属性基础,但每个对象的其余部分彼此不同。当从数据库中提取时,我可能会请求一个代理,并希望该代理下的整个层次结构。直接子代可以包括所有类型,每个子代可以有包含所有类型的子代。非常混乱,非常灵活。

我想我不太确定你希望完成什么,但我可以告诉你很多

首先,C#并不能提供一个很好的方法来完成我理解的你所期待的事情。您将无法使用泛型复制您所拥有的,因为您无法从泛型类型参数继承(从避免冲突的角度来看,这是有意义的)

也就是说,我会这样做:

public class AdjacencyTree<T> : AdjacencyTree
{
    public AdjacencyTree(int entityId, int entityTypeId) : base(entityId, entityTypeId) { }

    public T Value { get; set; }
}
var client1 = new AdjacencyTree<Client>(1, 4)
{
    Value = new Client()
    {
        first_name = "Pic'nic",
        last_name = "Basket #1",
        ssn = "123-45-6789"
    }
};
public class AdjacencyTree<T> : AdjacencyTree
{
    // ...

    public void AddChild<TChild>(int entityId, int entityTypeId, TChild child)
    {
        var child = new AdjacencyTree<TChild>(entityId, entityTypeId)
        {
            Value = child
        };
        this.AddChild(child);
    }
}
public AdjacencyUser(int entityId) : base(entityId, 3)
public List<AdjacencyTree> CreateSample()
{
    // build bottom of tree objects...
    var client1 = new AdjacencyClient(1, 4)
    {
        first_name = "Pic'nic",
        last_name = "Basket #1",
        ssn = "123-45-6789"
    };
    var client2 = new AdjacencyClient(2, 4)
    {
        first_name = "Pic'nic",
        last_name = "Basket #2",
        ssn = "234-56-7890"
    };
    var client3 = new AdjacencyClient(3, 4)
    {
        first_name = "Bear",
        last_name = "Cave",
        ssn = "345-67-8901"
    };
    var client4 = new AdjacencyClient(4, 4)
    {
        first_name = "Picnic",
        last_name = "Table",
        ssn = "456-78-9012"
    };

    // build the next level up and add the children...
    var officer1 = new AdjacencyUser(1, 3)
    {
        first_name = "Yogi",
        last_name = "Bear",
        officer_number = "YB123"
    };
    officer1.AddChild(client1);
    officer1.AddChild(client2);

    var officer2 = new AdjacencyUser(2, 3)
    {
        first_name = "Park",
        last_name = "Ranger",
        officer_number = "PR123"
    };
    officer2.AddChild(client3);
    officer2.AddChild(client4);

    // build the top of the tree and add the middle children...
    var agencyThatAlreadyExists = new AdjacencyAgency(1, 2)
    {
        agency_name = "Jellystone",
        agency_type = "Park",
    };
    agencyThatAlreadyExists.AddChild(officer1);
    agencyThatAlreadyExists.AddChild(officer2);

    return new List<AdjacencyTree>() { agencyThatAlreadyExists };
}
但这实际上取决于它是否有用。有些人可能会反对添加此项,因为它不必要地重复了构造函数参数。当然,这取决于你。这只是另一个例子

除此之外,我很想从所有东西中删除
entityTypeId
,除非您绝对需要它。这取决于您希望如何使用它,但我根据您的实现将其留在这里。看起来您可以根据
T
推断出它,但我也不确定为什么在实现中需要它

根据我的理解,即使没有包含泛型,您现有的传递构造函数也可能如下所示:

public class AdjacencyTree<T> : AdjacencyTree
{
    public AdjacencyTree(int entityId, int entityTypeId) : base(entityId, entityTypeId) { }

    public T Value { get; set; }
}
var client1 = new AdjacencyTree<Client>(1, 4)
{
    Value = new Client()
    {
        first_name = "Pic'nic",
        last_name = "Basket #1",
        ssn = "123-45-6789"
    }
};
public class AdjacencyTree<T> : AdjacencyTree
{
    // ...

    public void AddChild<TChild>(int entityId, int entityTypeId, TChild child)
    {
        var child = new AdjacencyTree<TChild>(entityId, entityTypeId)
        {
            Value = child
        };
        this.AddChild(child);
    }
}
public AdjacencyUser(int entityId) : base(entityId, 3)
public List<AdjacencyTree> CreateSample()
{
    // build bottom of tree objects...
    var client1 = new AdjacencyClient(1, 4)
    {
        first_name = "Pic'nic",
        last_name = "Basket #1",
        ssn = "123-45-6789"
    };
    var client2 = new AdjacencyClient(2, 4)
    {
        first_name = "Pic'nic",
        last_name = "Basket #2",
        ssn = "234-56-7890"
    };
    var client3 = new AdjacencyClient(3, 4)
    {
        first_name = "Bear",
        last_name = "Cave",
        ssn = "345-67-8901"
    };
    var client4 = new AdjacencyClient(4, 4)
    {
        first_name = "Picnic",
        last_name = "Table",
        ssn = "456-78-9012"
    };

    // build the next level up and add the children...
    var officer1 = new AdjacencyUser(1, 3)
    {
        first_name = "Yogi",
        last_name = "Bear",
        officer_number = "YB123"
    };
    officer1.AddChild(client1);
    officer1.AddChild(client2);

    var officer2 = new AdjacencyUser(2, 3)
    {
        first_name = "Park",
        last_name = "Ranger",
        officer_number = "PR123"
    };
    officer2.AddChild(client3);
    officer2.AddChild(client4);

    // build the top of the tree and add the middle children...
    var agencyThatAlreadyExists = new AdjacencyAgency(1, 2)
    {
        agency_name = "Jellystone",
        agency_type = "Park",
    };
    agencyThatAlreadyExists.AddChild(officer1);
    agencyThatAlreadyExists.AddChild(officer2);

    return new List<AdjacencyTree>() { agencyThatAlreadyExists };
}
从而消除了一些冗余。当然,这取决于两个“用户”类型始终具有相同的
EntityTypeId
,这可能公平,也可能不公平


我不确定我是否真的回答了你的问题,但希望它能指引你一个正确的方向

这可以使类层次结构强类型化,并符合
CreateSample
代码:

public abstract class AdjacencyTreeBase<T> where T : AdjacencyTreeBase<T>
{
    public AdjacencyTreeBase(int entityId, int entityTypeId)
    {
        EntityId = entityId;
        EntityTypeId = entityTypeId;
    }

    public long? Id { get; set; }
    public int? SystemId { get; set; }
    public int EntityId { get; set; }
    public int EntityTypeId { get; set; }
    public bool? isActive { get; set; }
    public long? lft { get; set; }
    public long? rgt { get; set; }

    public abstract void AddChild(T c);
    public abstract void RemoveChild(T c);
    public abstract List<T> ListChildren();
    public abstract void AddChildren(List<T> c);
    public abstract void ReplaceChildren(List<T> c);
}

public abstract class AdjacencyTree : AdjacencyTreeBase<AdjacencyTree>
{
    private List<AdjacencyTree> _children = new List<AdjacencyTree>();
    public List<AdjacencyTree> Children { get { return _children; } set { _children = value; } }

    public AdjacencyTree(int entityId, int entityTypeId) : base(entityId, entityTypeId) { }

    public override void AddChild(AdjacencyTree component)
    {
        _children.Add(component);
    }
    public override void AddChildren(List<AdjacencyTree> c)
    {
        _children = c;
    }
    public override void ReplaceChildren(List<AdjacencyTree> c)
    {
        _children = c;
    }
    public override void RemoveChild(AdjacencyTree component)
    {
        _children.Remove(component);
    }
    public override List<AdjacencyTree> ListChildren()
    {
        return _children;
    }
}

public class AdjacencyAgency : AdjacencyTree
{
    public string agency_name { get; set; }
    public string customer_number { get; set; }
    public string agency_type { get; set; }

    public AdjacencyAgency(int entityId, int entityTypeId) : base(entityId, entityTypeId)
    {
    }
}

public class AdjacencyUser : AdjacencyTree
{
    public string officer_number { get; set; }
    public string last_name { get; set; }
    public string first_name { get; set; }
    public string middle_initial { get; set; }

    public AdjacencyUser(int entityId, int entityTypeId) : base(entityId, entityTypeId)
    {
    }
}

public class AdjacencyClient : AdjacencyTree
{
    public string last_name { get; set; }
    public string first_name { get; set; }
    public string middle_initial { get; set; }
    public string ssn { get; set; }

    public AdjacencyClient(int entityId, int entityTypeId) : base(entityId, entityTypeId)
    {
    }
}

对于每个EntityTypeId,EntityID都是唯一的。如果没有EntityTypeId,这是不可能的。这是10年以上增长挑战的一部分。从用户开始,然后增加了代理和客户。这就是其他人“聪明地”认为每个实体的ID(UserId、ClientId等)可以映射到一个复合键以简化映射关系的点。从那时起,设备、客户和更多的产品被添加。让我明天玩,看看你的例子是否更容易阅读/使用。如果是这样的话,这就是答案。@KeithBarrows,这很公平。传统的东西从来都不好玩。我的观点是,您不需要在构造函数中接受typeId。我在最后一个代码块中添加了一个示例。当然,这是非常相切的,而且它是基于可能不真实的假设。只是一个建议。但是,对于泛型,它们确实会改变代码的流程。添加一个额外的属性级别既有好处(比如,如果您愿意,您的实体可以有一个
子属性,而现在这会导致冲突),也有缺点(额外键入?我真的不介意)。老实说,我会这么做,只是为了可读性,但我能想象的最大的用例是使用ORM。如果EF(或其他什么)正在为您序列化
User
对象,您就不必将它们映射到这个节点类型,这很方便。除此之外,它只是语义。我选择了构造函数中的两个参数,因为这总是必需的。没有任何情况下,任何对象都会在没有至少这两个数据的情况下被实例化。您这里的实际问题还不清楚。你想要什么?根据您的最后一段,听起来您只是想限制最后的类,只允许添加一种类型(它们自己)。但是
CreateSample
方法似乎建议您创建一个复合类型。你能更清楚地回答你要问的问题吗