在C#(ASP.Net MVC)中强制转换对象

在C#(ASP.Net MVC)中强制转换对象,c#,casting,object,C#,Casting,Object,我来自ColdFusion的背景,最终进入了现代,所以请耐心听我说 我在投射对象时遇到问题。我有两个数据库表作为模型使用——住宅和商业。他们两人共享他们的大部分领域,尽管每个领域都有一些独特的领域。我创建了另一个类作为包含所有属性字段总和的容器。查询住宅和商业,把它塞进我的容器,巧妙地称之为财产。这个很好用 但是,我在将住宅/商业领域的字段混淆到房地产领域时遇到了问题。为每个属性创建一个方法非常简单:fillPropertyByResidential(住宅源)和FillPropertyComme

我来自ColdFusion的背景,最终进入了现代,所以请耐心听我说

我在投射对象时遇到问题。我有两个数据库表作为模型使用——住宅和商业。他们两人共享他们的大部分领域,尽管每个领域都有一些独特的领域。我创建了另一个类作为包含所有属性字段总和的容器。查询住宅和商业,把它塞进我的容器,巧妙地称之为财产。这个很好用

但是,我在将住宅/商业领域的字段混淆到房地产领域时遇到了问题。为每个属性创建一个方法非常简单:fillPropertyByResidential(住宅源)和FillPropertyCommercial(商业源),并将变量别名。这也可以很好地工作,但很明显会复制一堆代码——所有这些字段在两个主要模型之间共享

因此,我想要一个通用的fillPropertyBySource(),它接受对象,并检测它是住宅还是商业,填充每个类型的特定字段,然后共同执行所有字段。除此之外,我在C#中收集到在If中创建的变量仅在If的范围内,因此我不确定如何做到这一点

    public property fillPropertyBySource(object source)
    {
        property prop = new property();
        if (source is Residential)
        {
            Residential o = (Residential)source;
            //Fill Residential only fields

        }
        else if (source is Commercial)
        {
            Commercial o = (Commercial)source;
            //Fill Commercial only fields
        }
        //Fill fields shared by both
        prop.price = (int)o.price;
        prop.bathrooms = (float)o.bathrooms;

        return prop;
    }
“o”为商业或住宅,仅存在于国际单项体育联合会的范围内。如何检测源对象的原始类型并采取措施

请容忍我——从ColdFusion到现代语言的转变是相当的。。。。。困难的更重要的是,我已经习惯了过程代码,MVC是一个巨大的范式转变

编辑:我应该包括错误:名称“o”在当前上下文中不存在
用于共享区域中价格和浴室的别名。

最好使用如下界面:

public interface IProperty 
{
   int price { get; set; }
   float bathrooms { get; set; }
}

public class Residential : IProperty
{
   public int price { get; set; }
   public float bathrooms { get; set; }
   //Other stuff...
}

public class Commercial : IProperty
{
   public int price { get; set; }
   public float bathrooms { get; set; }
   //Other stuff...
}
然后在方法中,使用接口而不是对象:

public property fillPropertyBySource(IProperty source)
{
    property prop = new property();
    if (source is Residential)
    {
        Residential o = (Residential)source;
        //Fill Residential only fields

    }
    else if (source is Commercial)
    {
        Commercial o = (Commercial)source;
        //Fill Commercial only fields
    }
    //Fill fields shared by both
    prop.price = source.price;
    prop.bathrooms = source.bathrooms;

    return prop;
}

当类具有要访问的公共属性时,将使用接口。您还可以拥有一个带有
price
bathrooms
的基类
Property
,并从中继承,以您喜欢的为准。

因为使用数据库生成的对象类型而不是分层定义的对象类型会对您施加人为约束,对于这个问题,真的没有优雅的解决方案。我能提供的最佳解决方案是使用分部类来附加已知接口,然后使用重载来完成复制对象时所需的最小工作量:

interface IPropertyBase
{
    decimal Price { get; set; }
    int Bathrooms { get; set; }
}

partial class Residential : IPropertyBase
{
}

partial class Commercial : IPropertyBase
{
}

class Property : IPropertyBase
{
 public decimal Price { get; set; }
 public int Bathrooms { get; set; }

    // Commercial
    public int Offices { get; set; }

    // Residential
    public int Bedrooms { get; set; }

    private void CopyFromBase(IPropertyBase o)
    {
        Price = o.Price;
        Bathrooms = o.Bathrooms;
    }

    public void CopyFrom(Commercial o)
    {
        CopyFromBase(o);

        Offices = o.Offices;
    }

    public void CopyFrom(Residential o)
    {
        CopyFromBase(o);

        Bedrooms = o.Bedrooms;
    }
}

一般来说,这种类型的“联合”对象通常是个坏主意。最好在IPropertyBase界面中定义公共属性,并在使用住宅/商业对象时将其保留为“本地”形式。例如,如果您需要创建一个区域中所有属性的组合集合,请创建一个
列表
,并直接使用它--它将保持列表中的对象完好无损(允许您在以后使用is/as运算符确定其原始类型,如果需要的话),并且不会有大量空对象的开销,每个对象上都有无意义的字段。

尼克,我是不是遗漏了什么?看起来这仍然会引发范围外的引用异常。。。?当然,我同意接口方法。@Gus-Woops没有对这些变量进行重命名,修正了!恐怕我没有听懂。住宅区和商业区通过Linq到SQL交易直接从数据库生成。我在代码中并没有它们的类定义。数据库中有“bathrooms”和“price”等字段,这是我需要从源对象获取的数据,并将其输入到我手工制作的“property”类中,该类也包含所有这些字段,我打算用住宅或商业数据填充这些字段。我不知道如何将接口添加到Linq to SQL生成的模型中,但住宅和商业已经有浴室和价格字段。@Mortanis-您可以通过分部类快速添加接口(或基类),有关详细信息,请参阅此问题:@Dan-非常感谢。这将控制器中的逻辑带回它所属的模型。很好!