简体   繁体   中英

C# how do i access a variable in another class?

This gets me the name of the class ("SolarPanel") but I want to get the value of the variable called "Name" (the one on line 30)

图片

Define virtual property like this:

/// <summary>
/// name: Building
/// </summary>
public class Building
{
    /// <summary>
    /// name of building
    /// </summary>
    public virtual string Name
    {
        get
        {
            // default name is class name with spaces between upper letters
            StringBuilder sb = new StringBuilder();
            bool wasUpper = false;
            foreach (char c in this.GetType().Name)
            {
                if (char.IsUpper(c))
                {
                    if (!wasUpper)
                    {
                        sb.Append(' ');
                        wasUpper = true;
                    }
                }
                else
                {
                    wasUpper = false;
                }
                sb.Append(c);
            }
            return sb.ToString().Trim();
        }
    }

    public void Construct()
    {
        string buildingName = this.Name;
        // do some work
    }
}

/// <summary>
/// name: Missile Station
/// </summary>
public class MissileStation : Building { }

/// <summary>
/// name: Radar Station "Buk"
/// </summary>
public class RadarBuk : Building
{
    /// <summary>
    /// overriden building name
    /// </summary>
    public override string Name { get { return @"Radar Station ""Buk"""; } }
}

You're trying to do up-casting which is bad thing (because there can be other descendants from Buildings class that have no such field). So, to play safe you have two options:

  • Move the field to the parent class (ie Buildings)
  • Override Construct() method as virtual one so descendants can alter the behavior and access their own fields

I assume you're constucting an instance of one of your inherited classes and you don't know what the type will be on construction (so SolarPanel.Name isn't an option).

You can do:

this.getType().GetProperty("Name").GetValue(this, null);

But if all your types don't have the Name property, you should null check GetProperty first:

var prop = this.getType().GetProperty("Name");
string name = "";

if (prop != null)
{
    name = prop.GetValue(this, null);
} 

Here is an approach with Attributes :

[AttributeUsage(AttributeTargets.Class)]
public class NameAttribute : Attribute {
    public readonly string Name;

    public NameAttribute(string name) {
        this.Name = name;
    }
}

public static class Extensions {
    /// <summary>
    /// If existant, returns the name tag for given object, else null
    /// </summary>
    public static string GetNameTag(this object instance) {
        return instance.GetType().GetNameTag();
    }

    /// <summary>
    /// If existant, returns the name tag for given type, else null
    /// </summary>
    public static string GetNameTag(this Type type) {
        object[] names = type.GetCustomAttributes(typeof(NameAttribute), false);
        switch(names.Length) {
            case 0:
                return null;
            case 1:
                return ((NameAttribute)names[0]).Name;
            default:
                throw new FormatException();
        }
    }
}

[Name("Headquater")]
public class Headquater : Building {
    // ...
}

[Name("Solar Panel")]
public class Solarpanel : Building {
    // ...
}

Now, you can simply do:

object panel = new SolarPanel();
Console.WriteLine(panel.GetNameTag());

And:

Console.WriteLine(typeof(SolarPanel).GetNameTag());

I dont agree with your class structure, but i will try to answer your question:

try this:

(string)this.GetType().GetField("Name").GetValue(this);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM