2013-10-22 132 views
0

我从某处获取类AAA的对象,我想在该对象中添加更多信息。所以,我正在创建一个从AAA派生的新类BBB。 BBB类具有附加的字段字典。我在派生类构造函数中填充此字典,该构造函数采用类AAA对象和我想用作字典键的项目数组,并且此字典的值是类AAA对象字段的元素。我试图在吹示例代码中创建类似的场景:扩展类的初始化?

void Main(){  
    A obj = new A() ; 
    obj.prop1 = new int [] {5 ,10, 15} ; 
    obj.prop2 = "Hello" ; 
    obj.prop3 = "World" ; 
// obj.Dump() ; 
    B obj2 = new B (new int [] {1,2,3}, obj) ;  
// obj2.Dump() ; 

} 

// Define other methods and classes here 
public class A { 
    public int [] prop1 ; 
    public string prop2 ; 
    public string prop3 ; 
} 

public class B : A { 
    public Dictionary <int, int> prop4 ; 
    public B (int [] keys, A a) { 
    prop4 = new Dictionary <int, int>() ; 
     if (keys.Length == a.prop1.Length) { 
      for (int i = 0 ; i < keys.Length ; i++) { 
       prop4.Add (keys[i], a.prop1[i]) ; 
      } 
      // is there a way to obsolete below lines of code??? 
      this.prop1 = a.prop1 ; 
      this.prop2 = a.prop2 ; 
      this.prop3 = a.prop3 ; 
     } 
     else { 
      throw new Exception ("something wrong") ; 
     }   
    } 
} 

在派生类构造函数中,我手动填充属性,我不想这样做。有没有另一种方式来做到这一点。我在我的实际班级中拥有超过20个物业。

+0

似乎更像你想要一个索引呢?它看起来像你想通过键访问整型数组中的值 - 你能解释一下用例吗?一旦你完成了这一次,你已经做到了 - 你计划与其他物体一起做这一百万次? – Charleh

+2

“prop1”,“prop2”,“prop3”和“prop4”的名字都很差。它们不代表相同的类型,也不以相同的方式使用。因此,如果您给他们的名称更清楚地表明了它们的用途,那将会非常有帮助。 –

+0

我想添加索引键不索引。 – User1551892

回答

2

不能做你问什么,但我会建议创建A类的拷贝构造函数和使用它与你的类B构造:

// Define other methods and classes here 
public class A 
{ 
    public int[] prop1; 
    public string prop2; 
    public string prop3; 

    public A() 
    { 
    } 

    public A(A orig) 
    { 
     prop1 = orig.prop1; 
     prop2 = orig.prop2; 
     prop3 = orig.prop3; 
    } 
} 

public class B : A 
{ 
    public Dictionary<int, int> prop4; 

    public B(int[] keys, A a) : base(a) 
    { 
     prop4 = new Dictionary<int, int>(); 

     if (keys.Length == prop1.Length) 
     { 
      for (int i = 0; i < keys.Length; i++) 
      { 
       prop4.Add(keys[i], prop1[i]); 
      } 
     } 
     else 
     { 
      throw new Exception("something wrong"); 
     } 
    } 
} 
+0

干净的实施没有副作用。可爱。 – Gusdor

+0

我感谢你的努力,但我不想修改我的基类实现。 – User1551892

+1

@ User1551892不想或不可以?简单的修改几乎总是比在解决方法中进行黑客更好!这种特殊的解决方法只涉及一个新的构造函数,仅此而已。 – Gusdor

0

B(您正在构建)的实例和A(您传递给B的构造函数)的实例不相关 - 它们具有不同的数据,它们位于不同的内存地址上。通过A的值更新B实例的属性/字段的唯一方法是复制。

0

Hmmmmmmm ......它有点不清,混淆你最多不过看看这个:

也许它没有涉及到你所需要的,但至少它可能会给你一个想法。

这是如何从一个类型的所有属性创建一个字典。

public static Dictionary<string, object> DictionaryFromType(object atype) 
{ 
    if (atype == null) return new Dictionary<string, object>(); 
    Type t = atype.GetType(); 
    PropertyInfo[] props = t.GetProperties(); 
    Dictionary<string, object> dict = new Dictionary<string, object>(); 
    foreach (PropertyInfo prp in props) 
    { 
     object value = prp.GetValue(atype, new object[]{}); 
     dict.Add(prp.Name, value); 
    } 
    return dict; 
} 

可以帮助你。如果不让我知道删除这个问题。

0

您在这里执行的操作与copy constructor非常相似。手工操作是我害怕的唯一方式!

我的建议是使用类的定义Properties和替换的属性为您的B类实现:

// Define other methods and classes here 
public class A 
{ 
    public virtual int[] prop1 { get; set; } 
    public virtual string prop2 { get; set; } 
    public virtual string prop3 { get; set; } 
} 

public class B : A 
{ 
    public Dictionary<int, int> prop4; 

    public override int[] prop1 
    { 
     get 
     { 
      return m_WrappedAInstance.prop1; 
     } 
     set 
     { 
      m_WrappedAInstance.prop1 = value; 
     } 
    } 

    public override string prop2 
    { 
     get 
     { 
      return m_WrappedAInstance.prop2; 
     } 
     set 
     { 
      m_WrappedAInstance.prop2 = value; 
     } 
    } 

    public override string prop3 
    { 
     get 
     { 
      return m_WrappedAInstance.prop3; 
     } 
     set 
     { 
      m_WrappedAInstance.prop3 = value; 
     } 
    } 

    A m_WrappedAInstance = null; 
    public B(int[] keys, A a) 
    { 
     m_WrappedAInstance = a; 
     prop4 = new Dictionary<int, int>(); 
     if (keys.Length == a.prop1.Length) 
     { 
      for (int i = 0; i < keys.Length; i++) 
      { 
       prop4.Add(keys[i], a.prop1[i]); 
      } 
     } 
     else 
     { 
      throw new Exception("something wrong"); 
     } 
    } 
} 

功能,这将采取类似行动。唯一的缺点是你的包装类A实例不能再独立于你的类B实例进行更改。这是一个要求吗?

+1

一些需要注意的是深层复制和浅层复制 - 我的意思是你想要引用指向相同的实例吗?这可能是一场噩梦,取决于需要复制的课程 - 只是认为我会在 – Charleh

+0

@Charleh中值得考虑 - 这就是为什么我总是主张在可以的时候用手去做。一旦进入“自动深度复制”,代码库变得复杂。我通常编写一个深层的副本:D – Gusdor

+1

Aye,但这取决于可序列化的东西 - 我不认为我真的*需要*编写一个拷贝构造函数,而不是.NET。总是一个更好的方式来处理这样的事情 – Charleh

0

定义的数组。再投的项目在数组中的各个属性

在B类的

public object[] properties; 

public int[] prop1 { 
    get { return (int[]) properties[0]; } 
    set { properties[0] = value; } } 

public string prop2 { 
    get { return (string)properties[1]; } 
    set { properties[1] = value ; } } 

构造

public B (int[] keys, A obj) 
    { 
     properties = A.properties; 
    }