在C#.NET中 sender.Equals 表示的是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C#.NET中 sender.Equals 表示的是啥?相关的知识,希望对你有一定的参考价值。

在C#.NET中 sender.Equals 表示的是什么?

是一个值?
还是一个控件名称?

比如说我现在有一个按钮事件
此时sender.Equals表示的是什么?

sender表示你产生事件的对象,比如你点击一个按钮,那么sender就表示该按钮;不过它是Object类型的;
一般按钮事件如下所示:
protected void btn_Click(Object sender, EventArgs e)

//按钮事件处理;


sender.Equals(另一个控件);这里的Equals()方法是属于所有Object类的;由于面向对象中所有类的基类是Object类,所以所有类都有这个方法~~;这个包含有继承的概念,你可以去了解一下;

由于sender是一个Object类的对象;固然就可以使用Equals()这个方法;
sender.Equals()表示的产生事件的对象与括号里的参数进行对比,看是否属于同一个对象~~

例如:
sender.Equals(new Button());表示看sender是否属于一个按钮对象,是都返回true,不是就返回false;
参考技术A Equals 是一个函数,是Object类的.所有的类都是Object的子类.所以每个对象都有这个函数.这个函数是做比较用的.
sender.Equals(一个控件对象);
返回应该是个bool值,表示这2个对象是不是同一个.
参考技术B Button button1 = new Button();
Button button2 = new Button();
TextBox text = new TextBox();

button1.Click += new EventHandler(button1_Click);

private static void button1_Click(object sender, EventArgs e)

sender.Equals(button1); //true
sender.Equals(button2); //false
sender.Equals(text); //false
参考技术C 这个表示的是Object类的Equals方法。以下为这个方法的官方说明:

确定指定的 Object 是否等于当前的 Object。

命名空间: System
程序集: mscorlib(在 mscorlib.dll 中)

语法
Visual Basic(声明)
Public Overridable Function Equals ( _
obj As Object _
) As Boolean

Visual Basic(用法)
Dim instance As Object
Dim obj As Object
Dim returnValue As Boolean

returnValue = instance.Equals(obj)

C#
public virtual bool Equals(
Object obj
)

Visual C++
public:
virtual bool Equals(
Object^ obj
)

J#
public boolean Equals(
Object obj
)

JScript
public function Equals(
obj : Object
) : boolean

参数
obj
类型:System..::.Object

与当前的 Object 进行比较的 Object。

返回值
类型:System..::.Boolean

如果指定的 Object 等于当前的 Object,则为 true;否则为 false。

异常
异常 条件
NullReferenceException obj 参数为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)。

备注
Equals 的默认实现支持引用相等性(对于引用类型)和按位相等性(对于值类型)。引用相等性是指进行比较的多个对象引用所引用的是同一个对象。按位相等性是指进行比较的多个对象具有相同的二进制表示形式。

请注意,派生类型可以重写 Equals 方法以实现值相等性。值相等性是指所比较的对象具有相同的值,即使它们具有不同的二进制表示形式也是如此。例如,请考虑两个分别表示数字 1.10 和 1.1000 的 Decimal 对象。Decimal 对象不具有按位相等性,因为它们具有不同的二进制表示形式,因此会考虑不同数量的尾随零。但是,这些对象具有值相等性,因为在进行比较时尾随零无关紧要,数字 1.10 和 1.1000 被视为相等。

给实现者的说明:

此方法可由派生类重写。例如,如果两个对象表示相同的值,则许多基数据类型返回 true;否则返回 false。

此方法仅比较基元和对象。若要比较更复杂的结构(如对象数组),必须重写该方法。

下面的语句对于 Equals 方法的所有实现均必须为真。在列表中,x、y 和 z 表示不为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing) 的对象引用。

除涉及浮点型的情况外,x.Equals(x) 都返回 true。请参见 IEC 60559:1989, Binary Floating-point Arithmetic for Microprocessor Systems。

x.Equals(y) 返回与 y.Equals(x) 相同的值。

如果 x 和 y 都为 NaN,则 x.Equals(y) 返回 true。

当且仅当 x.Equals(z) 返回 true 时,(x.Equals(y) && y.Equals(z)) 才返回 true。

只要不修改 x 和 y 引用的对象,对 x.Equals(y) 的相继调用将返回相同的值。

x.Equals(nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)) 返回 false。

有关属于 Equals 方法的其他必需行为,请参见 GetHashCode。

Equals 的实现必须不引发异常。

对于某些类型的对象,最好让 Equals 测试值相等性而非引用相等性。如果两个对象具有相同的“值”,那么即使它们不是同一实例,这样的 Equals 实现仍返回 true。类型实施者决定对象的“值”的构成,但这通常是存储在对象的实例变量中的部分或全部数据。例如,String 的值基于字符串的字符;对于两个按同样的顺序包含完全相同的字符的字符串实例,String 类的 Equals 方法返回 true。

实现 IComparable 的类型必须重写 Equals。

重写 Equals 的类型也必须重写 GetHashCode;否则,Hashtable 可能不正常工作。

如果编程语言支持运算符重载,并且您选择了重载给定类型的相等运算符,则该类型必须重写 Equals 方法。这样的 Equals 方法实现必须返回与相等运算符相同的结果。遵照此准则有助于确保使用 Equals 的类库代码(如 ArrayList 和 Hashtable)的行为方式与应用程序代码使用的相等运算符的方式一致。

下面是针对实现值类型的准则:

考虑重写 Equals,以便在 ValueType 上获得比 Equals 的默认实现所提供的性能增强的性能。

如果重写 Equals 并且语言支持运算符重载,则必须重载值类型的相等运算符。

下面是针对实现引用类型的准则:

如果引用类型的语义是基于该类型表示某个(些)值的事实,则考虑对该类型重写 Equals。

即使大多数引用类型重写 Equals,它们也必须不能重载相等运算符。但是,如果实现的引用类型想要具有值语义(如复杂的数字类型),则必须重写相等运算符。

示例
下面的代码示例将当前的实例与另一个对象进行比较

C# 复制代码
using System;

public class Sample
void Method()
Object Obj1 = new Object();
Object Obj2 = new Object();
Console.WriteLine(Obj1.Equals(Obj2)); //===> false
Obj2 = Obj1;
Console.WriteLine(Obj1.Equals(Obj2)); //===> true



下面的示例显示一个 Point 类,该类重写 Equals 方法以提供值相等和一个从 Point 派生的 Point3D 类。由于 Point 的 Equals 重写方法是引入值相等性的继承链中的第一项,因此不调用基类的 Equals 方法(从 Object 继承并检查引用相等性)。但是,因为 Point 以提供值相等性的方式实现 Equals,所以 Point3D.Equals 调用 Point.Equals。

C# 复制代码
using System;

class Point: Object
protected int x, y;

public Point()
this.x = 0;
this.y = 0;


public Point(int X, int Y)
this.x = X;
this.y = Y;


public override bool Equals(Object obj)
//Check for null and compare run-time types.
if (obj == null || GetType() != obj.GetType()) return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);


public override int GetHashCode()
return x ^ y;



class Point3D: Point
int z;

public Point3D(int X, int Y, int Z)
this.x = X;
this.y = Y;
this.z = Z;


public override bool Equals(Object obj)
return base.Equals(obj) && z == ((Point3D)obj).z;


public override int GetHashCode()
return base.GetHashCode() ^ z;



class MyClass

public static void Main()
Point point2D = new Point(5, 5);
Point3D point3Da = new Point3D(5, 5, 2);
Point3D point3Db = new Point3D(5, 5, 2);

if (!point2D.Equals(point3Da))
Console.WriteLine("point2D does not equal point3Da.");

if (!point3Db.Equals(point2D))
Console.WriteLine("Likewise, point3Db does not equal point2D.");

if (point3Da.Equals(point3Db))
Console.WriteLine("However, point3Da equals point3Db.");




// ----------------------------------
// Output should be:
//
// point2D does not equal point3Da.
// Likewise, point3Db does not equal point2D.
// However, point3Da equals point3Db.

Point.Equals 方法检查 obj 参数是否不为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing),并检查它引用的实例是否与该对象具有相同的类型。如果这两项检查中有任何一项失败,则方法返回 false。

Equals 方法使用 GetType 确定两个对象的运行时类型是否相同。(注意,这里不使用 typeof,因为它返回静态类型)。如果方法使用了 obj is Point 的检查形式,则在 obj 是 Point 的派生类实例的情况下,即使 obj 和当前实例的运行时类型不同,该检查也返回 true。验证了两个对象的类型相同后,该方法将 obj 转换为 Point 类型,并返回两个对象的实例变量的比较结果。

在 Point3D.Equals 中,完成任何其他事情之前首先调用继承的 Equals 方法;继承的 Equals 方法将检查 obj 是否不为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing),obj 是否是与此对象相同的类的实例,以及继承的实例变量是否匹配。只有当继承的 Equals 返回 true 时,该方法才比较在派生类中引入的实例变量。具体说来,除非 obj 已被确定为是 Point3D 类型或者是 Point3D 的派生类,否则不执行到 Point3D 的转换。

在前面的示例中,使用 operator ==(相等运算符)来比较各个实例变量。在某些情况下,适合使用 Equals 方法来比较 Equals 实现中的实例变量,如下面的代码示例所示。

C# 复制代码
using System;

class Rectangle
Point a, b;

public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY)
this.a = new Point(upLeftX, upLeftY);
this.b = new Point(downRightX, downRightY);


public override bool Equals(Object obj)
// Performs an equality check on two rectangles (Point object pairs).
if (obj == null || GetType() != obj.GetType()) return false;
Rectangle r = (Rectangle)obj;
//Uses Equals to compare variables.
return a.Equals(r.a) && b.Equals(r.b);


public override int GetHashCode()
return a.GetHashCode() ^ b.GetHashCode();



// Class Point added for clean compile
class Point
private int x;
private int y;

public Point(int X, int Y)
this.x = X;
this.y = Y;


public override bool Equals (Object obj)
// Performs an equality check on two points (integer pairs).
if (obj == null || GetType() != obj.GetType()) return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);


public override int GetHashCode()
return x.GetHashCode() ^ y.GetHashCode();




class MyClass
public static void Main()

Rectangle r1 = new Rectangle(0, 0, 100, 200);
Rectangle r2 = new Rectangle(0, 0, 100, 200);
Rectangle r3 = new Rectangle(0, 0, 150, 200);

if (r1.Equals(r2))
Console.WriteLine("Rectangle r1 equals rectangle r2!");

if (!r2.Equals(r3))
Console.WriteLine("But rectangle r2 does not equal rectangle r3.");


参考技术D 确认..

text 在C中使用*表示字符串

String is just an array of characters "char".

So instead of use "string" which is created in <cs50.h>, we use what's in the original C language: char *

	char *s = get_string("s: ");

* means a "pointer", it's the memory address of a variable. It tells you what address is this variable stored at.

So put it in a simple way, a "pointer" is just an "address". It's as simple as that.

A pointer, is a data item whose:

Value is a memory address
Type describes what type of data is located at the memory address

For example: 
int *x; 
So x is a pointer variable, means that x is stored an memory address. And 'int' in the front means in that address, a integer type of variable is stored.

So for example:
int k;
k = 5;

So 'k' is an integer variable, with a value of 5.

int *pk;  // This means 'pk' is a pointer variable, it stores an memory address, and at this address, an integer type of variable is stored.

pk = &k;  // '&' gets the memory address of a variable. So here 'pk' gets the address of the integer variable 'k'.


For a string variable, the "s" variable stores the memory address of a char, which is the first char of the string.

For string variables, it's different from other type of variables. For other variables, like an int, you can just directly compare the value of 2 int variables. But it's different for string variables.

Because a string is always an array of char, and the end of a string always is '\0', we only need to know the memory address of the first char of the string, then we'll be able to know what the whole string is. Because when we know the address if the first char, we only need to look at the next bite to know the next char in the string, until we reach '\0'. 

That's why when we use: string s = get_string("s: ");

What "s" is storing is not the actually content of the string, but the memory address of the first char. 

That's why when we get 2 strings, even if the string contents are the same, if you compare the string variables directly, they will not be the same. Because each string variable stores the memory address of that string. And those addresses are obviously different.

string s = get_string("s: );
string t = get_string("t: );

So if we put the same string content for "s" and "t", but the address for "s" string might be 100, but the address for "t" string might be 300. So if you just compare "s" and "t" directly, you are actually comparing the memory addresses for "s" and "t". So they are different for sure. Even if the string contents might be exactly the same.

so "if(s == t)" is always going to be false, because they are 2 different memory addresses. But if those are int variables, then it's actually comparing the value not the memory addresses. It's very different for string variables.


So if we want to copy a content of one string into another, we can't simply do like this:

    // get a string
    string s = get_string("s: ");

    // copy string's address
    string t = s;

This way the content of the string are NOT copied. Because both "s" and "t" stores the string's memory address, not the string contents. So doing
    string t = s;
Only copied the address of "s" to "t". So now both "t" and "s" are the same address, these 2 pointers are pointing to the same address.

Therefore we actually didn't get another string, they are basically the same one. Change the chars in "t" would also change "s".


So, if we want to really copy the content of string "s" to another brand new string "t", we need to use "malloc()" to allocate new memory spaces for "t", and then copy the contents.
    // get a string
    char *s = get_string("s: ");
    if (!s)
    {
        return 1;
    }

    // allocate memory for another string
    char *t = malloc((strlen(s) + 1) * sizeof(char));
    
    if (!t)
    {
        return 1;
    }

    // copy string into memory
    for (int i = 0, n = strlen(s); i <= n; i++)
    {
        t[i] = s[i];
    }

* Copy string contents into the new memory block can also be written using "strcpy(des, src);" The result is the same. Main thing is to allocate new memory block for string "t" first.


2 ways to use *:

1. To declare a variable:
	char *t = get_string("t: ");
	
	One thing to be aware of when declaring a pointer variable:
	
	If you declare multiple same type of pointer variables in a single line, you need to add '*' before each variable name:
	
	int *px, *py, *pz;
	
	You can't write like this: int* px, py, pz; This way only 'px' is a pointer, py and pz are just int variables not a pointer.
	
	
2. To point to an address in the memory, and get the value that's stored in that address:

  '*' is also called dereferencing operator here. Refer to the snippet about "Dereferencing Pointer in C".

An array's name, is actually just a pointer to its first element. So that means the array name is a pointer variable that stores the address of the first element of the array. So if the array name is 'arr', the arr[i] is the ith element in this array, the address of this element is: arr + i;

So if 's' is a string, which is really an array of char. So 's' is the name of this array s[i];

If we want to print each character in this string 's':

    // print string, one character per line
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c\n", *(s + i));
    }
    
So the *(s+i) is the same as writing as s[i]. They work exactly the same, just different way of writing the code.

"printf("%c\n", *(s + i));" means: print out the char at the location or address of "s" or "s+i".
* means the memory address of something.
*(s+i): with the * at the front means: go to that address, and get the value stored in that memory address.

This is also called: De-referencing:   x = *p;   Read: Assign to x the value pointed to by p. So go to the memory address p, get the value that's stored in this address, then assign this value to x.

So "s" is a pointer. If just "s", it's the address of a variable. If I add * in the front, it means the content that's stored in that address, which is the value of that variable.

"s" is the address;
"*s" is the value that's stored in that address.



	

以上是关于在C#.NET中 sender.Equals 表示的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

C#.NET重点知识点汇总

XML在C#ASP.NET的作用?

C#/.NET 多线程任务Task的详解——应用实例

2021-05-17 C#.NET面试题 说说对http 301302303,304400405415状态码的认识;

导出的 C 函数与结构与 .Net 编组中的布尔大小

C语言中选择排序和冒泡排序