C# 如何确定属性/字段是否为引用类型(使用反射)
我已经签出了链接。有一个问题是,通常有一个不确切的术语“参考”。所以首先我想澄清一下,在我看来,什么时候类型是引用类型C# 如何确定属性/字段是否为引用类型(使用反射),c#,reflection,C#,Reflection,我已经签出了链接。有一个问题是,通常有一个不确切的术语“参考”。所以首先我想澄清一下,在我看来,什么时候类型是引用类型 string bla = "abc"; string blob = bla; bla = "cde"; // bla = "cde" and blob = "abc" 这是非引用类型的行为 string bla = &
string bla = "abc";
string blob = bla;
bla = "cde";
// bla = "cde" and blob = "abc"
这是非引用类型的行为
string bla = "abc";
string blob = bla;
bla = "cde";
// bla = "cde" and blob = "abc"
这是引用类型的行为
Person jens = new Person("Jens");
Person frank = jens; // doesn't make any sense i know
frank.Name = "Frank";
//jens.Name = "Frank" and frank.Name = "Frank"
正如您所看到的,一旦引用,只有类型传递引用(如c中的指针)。您还可以通过使用ref关键字来实现非引用类型的行为
我搜索的是Type类的一个属性,它指示该类型是否为引用类型
它也应该适用于结构,只适用于任何可以“存储”某些内容的东西
根据我在上面提供的链接,有多个属性,都略有不同
- 一类
- 基本的
- IsValueType
对不起,我的英语不好:)
IsValueType
是您要找的
请注意:
string
实际上是一种引用类型。string
是一种特殊的内置类型,如Int32
或Double
,它具有特殊的属性,可以用C#将其表示为文字值。两者都是,我想这可能与你正在努力解决的问题有关
我的猜测是,你对C#中引用的含义做出了一些错误的假设。两种语言中都使用了reference
和struct
这两个词,但它们各自的含义非常不同
在第二个示例中,frank
和jens
都是对同一实际对象的引用。可以将它们看作是指向内存中相同地址的指针,因为它们在内存中的某个地方
看起来您认为当您将jens
分配给frank
时,您正在调用一个复制构造函数。如果<代码> JNEs/COD>和String
或(显然)Person
,您需要明确地执行此操作
// Assume Person has a Person(String name) constructor
Person bob = new Person("Bob");
// This assigns a **reference to bob** to a new reference variable.
// steve and bob are now referencing the same object. Not what you want.
Person steve = bob;
// Person should have a copy constructor. If that's done correctly,
// this will create a COPY of the object that both steve and bob
// refer to.
Person bob2 = new Person(steve);
// Because we explicitly created a new instance for bob2, this won't
// affect the other "Bob" instance that bob and steve still refer to.
bob2.Name = "Bob Junior";
C#中的“非引用”类型称为struct
<代码>日期时间就是一个例子。复制时,C<代码>结构> /COD>就像堆栈上的C++类实例:有一个隐式拷贝。
// DateTime is a struct. It's IsValueType, NOT IsClass.
// Different behavior.
DateTime today = DateTime.Now.Date;
// This creates a copy, because DateTime is a struct not a class.
DateTime alsoToday = today;
这仅仅是(值得称赞的)对语言的普遍好奇,还是你正在试图解决一个特定的问题?我经常发现,当有人问“你为什么真的要这么做?”时,答案会让我们比专注于你试图用来解决问题的特定技术时更有帮助。像这样的问题通常是暗示OP从错误的解决方案开始 你的两种方法做了两件不同的事情。在第一个示例中,您为
X
赋值,在第二个示例中,您为X.a
赋值,然后询问“为什么X
的值没有改变。@ScottChamberlain我先对X=y进行赋值,然后再对y.A进行赋值,只是为了表明X.A已经变为yes,但对于字符串版本,您不会执行y.A
。如果类String
具有公共setter的属性,则可以对其执行相同的操作。要使示例等效,请替换frank.Name=“frank”代码>与jens=新人(“弗兰克”)代码>并查看frank和jens的价值。在处理字符串时,假设只键入“stuff”
实际上是在做新字符串(新字符[]{'s','t','u','f','f'})
,您看到的行为更有意义。@ScottChamberlain您是对的,但是在上面的示例中,如果使用'int'而不是'String'?事实上,我只是想展示我的行为举止。我是一个没有经验的程序员,所以如果我写的问题不总是100%准确的话,请原谅我。字符串的赋值运算符不显示值语义。所有字符串都是,是一个没有公共setter的类。它是一个不可变的对象。“假装是值类型”一点也不奇怪只要你使用返回字符串的方法(包括操作符+
),只读对象就会创建新的只读对象这不仅是一个事实上错误的答案,它也没有解决OP困惑的明显根源。我曾经在德语背景下学习c语言编程,所以我一直在为这些名字而挣扎。不变性这个词对我来说是新的。所以非常感谢你的帮助。@LuckyLike有一件事我忘了提:你在这里想要实现的实际目标是什么?