Abi*_*tro 5 .net c# inheritance class-design multiple-inheritance
我的首席技术官(首席技术官)让我想出了一种方法,他可以在基类中编写一个单独的函数,并可以访问子类的所有属性.这是我想出的 -
基类
class Assets
{
public Assets getPropertyVal(Assets asObj)
{
PropertyInfo[] propInfos = asObj.GetType().GetProperties();
string strAttributeValue = "10";
foreach (PropertyInfo propInfo in propInfos)
{
// Getting the value
var propValue = propInfo.GetValue(asObj, null);
// Setting the value
propInfo.SetValue(asObj, Convert.ChangeType(strAttributeValue, propInfo.PropertyType), null);
}
return asObj;
}
}
Run Code Online (Sandbox Code Playgroud)
儿童班
class House : Assets
{
public int rooms{get; set;}
}
Run Code Online (Sandbox Code Playgroud)
Program.cs文件
class Program
{
static void Main(string[] args)
{
House hsObj = new House();
hsObj.rooms = 5;
Assets asObj = hsObj.getPropertyVal(hsObj);
// Returns asObj as JSON
}
}
Run Code Online (Sandbox Code Playgroud)
现在这个工作正常,但我只是想知道在C#中是否有更好的方法来做到这一点.
请注意,我们不知道 子类中将存在哪些属性,因此必须在运行时确定.
更新:说清楚,我只是想知道是否有更好的方法来访问子类属性,一个不使用反射.需要注意的重要一点是,我们不知道子类可能具有哪些属性.
更新#2 :我正在使用具有许多实体的产品.这些实体具有不同的属性.我希望能够在一个地方访问和使用所有这些属性.这个功能正是如此.这是我可以访问所有数据的一个地方.
首先,你的Program.cs实际上并没有"做"你想要的东西.听起来你想要一个程序,这样你就可以这样做:
Asset myAsset = new House();
myAsset.Rooms = 5;
Run Code Online (Sandbox Code Playgroud)
但是,为什么你甚至想要这样做呢?如果您的资产不是众议院,则会抛出异常,因此您需要首先检查:
if (myAsset is House)
myAsset.Rooms = 5;
Run Code Online (Sandbox Code Playgroud)
那时候,你可能只是把它投到了一所房子里.听起来您可能想要使用PropertyBag或Dictionary而不是继承.
我想你所描述的就是这个.请注意,选项1并不真正限制哪些属性可用于哪些类,因此我猜这不会对您的特定情况起作用.
// Option 1, a Property Bag (Note: this replaces the properties on the classes)
class Asset
{
Dictionary<string, object> myPropertyBag = new Dictionary<string, object>();
public T GetProperty<T>(string property)
{
// This throws if the property doesn't exist
return (T)myPropertyBag[property];
}
public void SetProperty<T>(string property, T value)
{
// This adds the property if it doesn't exist
myPropertyBag[property] = (object)value;
}
}
// Option 2, use a switch and override this function in derived classes
class Asset
{
public int SomePropertyOnAsset { get; set; }
public virtual T GetProperty<T>(string property)
{
switch (property)
{
case "SomePropertyOnAsset": return this.SomePropertyOnAsset;
default: throw new ArgumentException("property");
}
}
public virtual void SetProperty<T>(string property, T value)
{
switch (property)
{
case "SomePropertyOnAsset": this.SomePropertyOnAsset = (int)value;
default: throw new ArgumentException("property");
}
}
}
class House : Asset
{
public int Rooms { get; set; }
public virtual T GetProperty<T>(string property)
{
switch (property)
{
case "Rooms": return this.Rooms;
default: return base.GetProperty<T>(property);
}
}
public virtual void SetProperty<T>(string property, T value)
{
switch (property)
{
case "Rooms": this.Rooms = (int)value;
break;
default: base.SetProperty<T>(property, value);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,这就是你如何使用它们:
// Option 1
Asset asset = new House();
asset.SetProperty("Rooms", 5);
var rooms = asset.GetProperty<int>("Rooms");
// Option 2
Asset asset = new House();
asset.SetProperty("Rooms", 5);
asset.SetProperty("SomePropertyOnAsset", 10);
asset.SetProperty("SomethingElse", 15); // Throws ArgumentException
Run Code Online (Sandbox Code Playgroud)
第三个选项是使Asset成为DynamicObject. http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx
如果您不能或不想对Asset基类进行重大更改或触摸每个实体,则可能需要使用反射.