在C#中将值类型更改为引用类型的最佳方法是什么?

时间:2014-05-27 21:26:36

标签: c# entity-framework reference

我有三个类定义如下:

public class Base
{
    public int Id { get; set; }
}

public class Bar : Base { ... }

public class Foo : Base
{
    public int? ParentId { get; set; }
    public Base Parent { get; set; }

    public int? FooParentId { get; set; }
    public Foo FooParent { get; set; }

    public int? BarParentId { get; set; }
    public Bar BarParent { get; set; }

    public Foo(Foo parent)
    {
        FooParent = parent;
        FooParentId = parent.Id;

        Parent = FooParent; // Now changes to Parent are reflected on FooParent
        ParentId = FooParentId; // Changes to ParentId are not reflected because it is a value type.
    }
    public Foo(Bar parent)
    {
        // Same implementation as ctor(Foo parent);
    }
}

我尝试做的是Parent引用FooParentBarParent(我认为相当简单),然后ParentId引用{{ 1}}或FooParentId。使BarParentId成为引用类型的最理智的方法是什么?

答案here提到整数的装箱/拆箱有很多与之相关的问题 这真的是一个糟糕的解决方案吗?

修改
我应该提到ParentIdFoo是实体框架表。 Bar是一个对象,可以是一个表或另一个表的子节点,对于Entity Framework代码 - 首先要正确生成表,必须定义FooFooParent。此外,BarParent可能不会在其getter中引用ParentId。实体框架也应该归咎于此。致电Parent时,实体框架Reinserts Existing Objects。所有非空的父母都会被重新插入。

3 个答案:

答案 0 :(得分:1)

如果您的双手被EF绑定,您可以使用委托来根据构造函数中传递的类型传播ParentId的更改。我不知道EF是否会抱怨这个。

例如,使用Action<T>委托,我们可以将更改转发至ParentId到相应的[Foo|Bar]ParentId

public class Base
{
    public int Id { get; set; }
}

public class Bar : Base {  }

public class Foo : Base
{
    private int? _parentId;

    public int? ParentId { 
        get{ return _parentId; } 
        set{ 
            _parentId = value;
            if( OnParentChangeAction != null ) {
                OnParentChangeAction( _parentId ); 
            }
        } 
    }

    public Base Parent { get; set; }

    public int? FooParentId { get; set; }
    public Foo FooParent { get; set; }

    public int? BarParentId { get; set; }
    public Bar BarParent { get; set; }

    private Action<int?> OnParentChangeAction{ get; set; }

    public Foo(Foo parent)
    {
        FooParent = parent;
        FooParentId = parent.Id;

        Parent = FooParent;
        ParentId = FooParentId;
        OnParentChangeAction = newParentId => FooParentId = newParentId;
    }
    public Foo(Bar parent)
    {
        BarParent = parent;
        BarParentId = parent.Id;

        Parent = BarParent; 
        ParentId = BarParentId; 
        OnParentChangeAction = newParentId => BarParentId = newParentId;
    }
}

答案 1 :(得分:0)

由于您已经引用了父对象,因此可以使用属性获取其Id:

    public int? ParentId 
    { 
        get
        {
            return Parent != null ? Parent.Id : null;
        }
    }

答案 2 :(得分:0)

您可以为getset属性的FooParentIdBarParentId访问者添加逻辑,但同意@Servy这是一个糟糕的设计。

原因甚至不仅是ID-s和引用对象。我不明白为什么你需要同时拥有BarParent和FooParent,只有1个IParent类型的属性,然后使用该接口提供的方法与它进行通信,利用继承和多态的所有好处。