【问题标题】:How can I determine if a variable is of Type Reference in C#?如何确定变量是否属于 C# 中的类型引用?
【发布时间】:2011-05-27 12:03:06
【问题描述】:
StringBuilder first = new StringBuilder();
StringBuilder second = first;

String str = "Love";

有没有办法检查变量“second”是否为类型引用,而变量“str”是否为类型值?我一直在谷歌搜索仍然无法得到它,这里的 C# 非常新。我知道有 second.getType() 但这并不能让我知道 second 是否属于类型引用。

非常感谢。

附加信息

在这里,我想坦率地说,我正面临 C Sharp 的编程测试,当然这是一个开卷测试,因为我不在封闭或受限的课程中 :-) 。我更熟悉 PHP、C/C++、Perl,但在 C 语言方面非常陌生,但我喜欢学习它。这是他们的测试。我已经填写了几个函数,只漏掉了 2 或 3 个,分别是 ref 和 unref。如果您看到下面的代码,我需要在 PrintSortedData 函数中打印出 之间的引用类型。测试问题在代码的注释中。可能我还没有弄好编程逻辑。

/// The DataObject class stored with a key
class DataObject
{
    public string key = "";
    public int value = 0;
    // Populate
    public DataObject(string k, int v = 0)
    {
        key = k;
        value = v;
    }

}

class Program
{
    static Hashtable Data = new Hashtable();
    static string[] StaticData = new string[] { "X-Ray","Echo","Alpha", "Yankee","Bravo", "Charlie", 
        "Delta",    "Hotel", "India", "Juliet", "Foxtrot","Sierra",
        "Mike","Kilo", "Lima",  "November", "Oscar", "Papa", "Qubec", 
        "Romeo",  "Tango","Golf", "Uniform", "Victor", "Whisky",  
         "Zulu"};

    static void Main(string[] args)
    {
        for (int i = 0; i < StaticData.Length; i++)
            Data.Add(StaticData[i].ToLower(), new DataObject(StaticData[i]));
        while (true)
        {
            PrintSortedData();
            Console.WriteLine();
            Console.Write("> ");
            string str = Console.ReadLine();
            string[] strs = str.Split(' ');

            if (strs[0] == "q")
                break;
            else if (strs[0] == "print")
                PrintSortedData();
            else if (strs[0] == "swap")
                Swap(strs[1], strs[2]);
            else if (strs[0] == "ref")
                Ref(strs[1], strs[2]);
            else
                Console.WriteLine("Invalid Input");
        }
    }

    /// <summary>
    /// Create a reference from one data object to another.
    /// </summary>
    /// <param name="key1">The object to create the reference on</param>
    /// <param name="key2">The reference object</param>
    static void Ref(string key1, string key2)
    {

    }

    /// <summary>
    /// Removes an object reference on the object specified.
    /// </summary>
    /// <param name="key">The object to remove the reference from</param>
    static void UnRef(string key)
    {
        // Populate
    }



    /// <summary>
    /// Prints the information in the Data hashtable to the console.
    /// Output should be sorted by key 
    /// References should be printed between '<' and '>'
    /// The output should look like the following : 
    /// 
    /// 
    /// Alpha...... -3
    /// Bravo...... 2
    /// Charlie.... <Zulu>
    /// Delta...... 1
    /// Echo....... <Alpha>
    /// --etc---
    /// 
    /// </summary>
    static void PrintSortedData()
    {
        // Populate
        ArrayList keys = new ArrayList(Data.Keys);
        keys.Sort();

        foreach (object obj in keys)
        {
            Console.Write(obj + "......." + ((DataObject)Data[obj]).value + "\n");
        }
    }
}

【问题讨论】:

  • firstsecondstr所有引用。在这种情况下,firstsecond 都指向同一个对象。

标签: c# .net types reference


【解决方案1】:

firstsecond 都是 StringBuilder 类型的引用。它们碰巧是对同一个对象的引用;换句话说,它们具有相同的对象标识strString 类型的引用。

【讨论】:

  • 非常感谢 Cody Gray 进一步澄清了我的问题,Cody Gray:“至于您的隐含问题,您如何确定包含您直接实例化的对象的变量之间的区别,以及一个包含对该对象的隐式引用的变量,好吧,你不能。“
  • @William,他是对的。你不能那样做。具有相同对象标识的两个引用无法区分。
  • 谢谢。请查看我在上面的问题中添加的其他信息,以了解我为什么需要它。谢谢
【解决方案2】:

两个变量都是引用类型。对象StringBuilder 的实例仍然是引用类型,string 类型的对象也是。

C# 中的值类型可以是用户定义的structs、枚举和数字类型(例如intfloatdoubledecimal 等)请参阅Value Types 上的文档了解更多信息。

引用类型是其他一切,包括类、接口、委托,甚至是一些内置类型,如stringobject。请参阅Reference Types 上的文档以了解更多详细信息。


至于您的隐含问题,您如何确定包含您直接实例化的对象的变量与包含对该对象的隐式引用的变量之间的区别,嗯,您不能。在 C# 中,这些是相同的。两个变量都不包含该对象,而是指向该对象的指针(即对该对象位置的间接引用)。

当然,不必担心无法区分两者,因为它们具有完全相同的功能。如果你修改了其中一个指向的对象,你也修改了另一个指向的对象。

【讨论】:

  • “就您的隐含问题而言,您如何确定包含您直接实例化的对象的变量与包含对该对象的隐式引用的变量之间的区别,嗯,您不能。” - Cody Gray,这正是我想知道的。那么有没有其他方法呢?
  • @William:阅读第二段。该功能不是遗漏,它根本没有意义。变量完全相同。如果你修改了其中任何一个指向的对象,那么它们都指向的对象会被修改。编译器/运行时并不关心你最初创建的对象是哪个。就它而言,没有区别。想象一下,这些对象在内存中占据相同的位置,比如它们的街道地址。如果我给两个人相同的地址,他们都会到我家。这里的情况是一样的。
  • 感谢科迪·格雷。我在想的是,值变量就像房子的土地,它真的在物理上持有房子,而参考变量就像一张纸,它的逻辑地址指向房子的地址。当然,它们都在同一个位置,土地是物理的,但地址是逻辑的,但只有地址才能真正帮助我们指出如何去那个土地。所以我想知道我持有的是纸质地址还是土地?请参阅我在上面的问题中添加的其他信息,以了解我为什么需要它。谢谢
【解决方案3】:

在这里,我想坦率地说,我正面临 C Sharp 的编程测试。我更熟悉 PHP、C/C++、Perl,但在 C 语言方面非常陌生,但我喜欢学习它。这是他们的测试。我已经填了几个函数,只漏掉了2、3个,就是

/// The DataObject class stored with a key
class DataObject
{
    public string key = "";
    public int value = 0;
    // Populate
    public DataObject(string k, int v = 0)
    {
        key = k;
        value = v;
    }

}

class Program
{
    static Hashtable Data = new Hashtable();
    static string[] StaticData = new string[] { "X-Ray","Echo","Alpha", "Yankee","Bravo", "Charlie", 
        "Delta",    "Hotel", "India", "Juliet", "Foxtrot","Sierra",
        "Mike","Kilo", "Lima",  "November", "Oscar", "Papa", "Qubec", 
        "Romeo",  "Tango","Golf", "Uniform", "Victor", "Whisky",  
         "Zulu"};

    static void Main(string[] args)
    {
        for (int i = 0; i < StaticData.Length; i++)
            Data.Add(StaticData[i].ToLower(), new DataObject(StaticData[i]));
        while (true)
        {
            PrintSortedData();
            Console.WriteLine();
            Console.Write("> ");
            string str = Console.ReadLine();
            string[] strs = str.Split(' ');

            if (strs[0] == "q")
                break;
            else if (strs[0] == "print")
                PrintSortedData();
            else if (strs[0] == "swap")
                Swap(strs[1], strs[2]);
            else if (strs[0] == "ref")
                Ref(strs[1], strs[2]);
            else
                Console.WriteLine("Invalid Input");
        }
    }

    /// <summary>
    /// Create a reference from one data object to another.
    /// </summary>
    /// <param name="key1">The object to create the reference on</param>
    /// <param name="key2">The reference object</param>
    static void Ref(string key1, string key2)
    {

    }

    /// <summary>
    /// Removes an object reference on the object specified.
    /// </summary>
    /// <param name="key">The object to remove the reference from</param>
    static void UnRef(string key)
    {
        // Populate
    }



    /// <summary>
    /// Prints the information in the Data hashtable to the console.
    /// Output should be sorted by key 
    /// References should be printed between '<' and '>'
    /// The output should look like the following : 
    /// 
    /// 
    /// Alpha...... -3
    /// Bravo...... 2
    /// Charlie.... <Zulu>
    /// Delta...... 1
    /// Echo....... <Alpha>
    /// --etc---
    /// 
    /// </summary>
    static void PrintSortedData()
    {
        // Populate
        ArrayList keys = new ArrayList(Data.Keys);
        keys.Sort();

        foreach (object obj in keys)
        {
            Console.Write(obj + "......." + ((DataObject)Data[obj]).value + "\n");
        }
    }
}

【讨论】:

  • 不确定这与您的原始问题有何关系。如果您想问其他问题,请创建一个新问题。如果您想在原始帖子中添加一些内容,请使用“编辑”按钮,但请不要在下面将其作为答案发布。而且我不明白您对 Ref 函数的意图,但似乎这可能行不通。
  • 感谢布朗博士,对不起我的无知,在我添加之后我意识到我应该编辑它而不是添加它。我添加而不是编辑的原因是因为在其他论坛中,我尝试编辑而不是添加回复,我被那里的回复者责骂说“你必须做出回复而不是编辑,这样人们就可以请参阅对话的线性和逻辑流程”但情况恰恰相反。但我会在这里调整风格。我也是这个论坛的新手。谢谢。
  • 操作,顺便说一句,这仍然与我原来的问题有关,这不是一个新问题。因为我试图解释为什么我需要确定一个变量是持有一个真实的对象还是只是一个引用。
猜你喜欢
  • 2020-01-01
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
  • 2013-02-21
  • 1970-01-01
  • 2011-09-10
  • 2014-01-17
  • 1970-01-01
相关资源
最近更新 更多