Read-only archive. Login and posting are unavailable.
View Full Version : [Hỏi] dùng equals trong linq
toi_yeu_quyen
16-02-2020, 15:26
Em mới học về C# và linq, có trường hợp này em muốn hỏi các bác:
Class 1: class(int id, string name, Address address)
Class 2: student(int id, string name, Address address, int classID)
Address(string City, string village)
Em tạo 2 List là List students và List classes
Em muốn join 2 bảng này với nhau bằng linq bằng từ khóa join chứ không dùng cross join 2 bảng nên viết như sau:
var query = from s in students
join c in classes
on s.address equals c.address
select new
{
name= s.Name,
classname= c.Name,
city= c.address.City};
join như này thì không trả ra kết quả vì so sánh 2 object nên nó không bằng nhau nhưng nếu viết theo kiểu này thì nó lại trả ra được kết quả đúng
var query1 = from c in classes
join s in students on new { c.address.City, c.address.Villaes }
equals new { s.address.City, s.address.Villaes }
select new
{
name= s.Name,
classname= c.Name,
city= c.address.City
};
Tại sao 2 thằng cùng equals object mà 1 ông trả kết quả được 1 ông lại không vậy bác, có cách nào override lại cái equals này được không? Nhân tiện các bác cho em ví dụ thông não vụ delegate với, em đọc cũng không hiểu cách dùng của nóhttps://i.imgur.com/Wz51zuD.png
dreamnight
16-02-2020, 17:36
Em mới học về C# và linq, có trường hợp này em muốn hỏi các bác:
Em tạo 2 List là List students và List classes
Em muốn join 2 bảng này với nhau bằng linq bằng từ khóa join chứ không dùng cross join 2 bảng nên viết như sau:
join như này thì không trả ra kết quả vì so sánh 2 object nên nó không bằng nhau nhưng nếu viết theo kiểu này thì nó lại trả ra được kết quả đúng
Tại sao 2 thằng cùng equals object mà 1 ông trả kết quả được 1 ông lại không vậy bác, có cách nào override lại cái equals này được không? Nhân tiện các bác cho em ví dụ thông não vụ delegate với, em đọc cũng không hiểu cách dùng của nóhttps://i.imgur.com/Wz51zuD.png
Để làm theo kiểu Senior thì bạn phải vô lớp Address override 2 hàm Equals() và GetHashCode()
public class Address
{
public string Street { get; set; }
public override bool Equals(object obj)
{
// Compare property, if matches, so object is equal
return ((Address)obj).Street == this.Street;
}
public string GetHashCode()
{
// Hash code must be equal between two objects
return this.Street.GetHashCode();
}
}
Code trên vì sao thì chịu khó Google nhé. Còn giải quyết theo kiểu Junior thì bạn phải so sánh 2 property con của Address ở đoạn "on o.Address equals a.Address" thay bằng "on o.Address.Street equals a.Address.Street"
:go::go:
dreamnight
16-02-2020, 17:49
Tại sao 2 thằng cùng equals object mà 1 ông trả kết quả được 1 ông lại không vậy bác, có cách nào override lại cái equals này được không?
Cái này giải thích thì hơi Senior tý, đại khái anonymous type (bằng khai báo từ khóa new { A="a" } ) sẽ được coi như Equal nếu toàn bộ property con của nó bằng nhau. Theo code của bạn ở trên thì City và Villaes nếu bằng nhau thì 2 Address được coi là Equal.
Nhân tiện các bác cho em ví dụ thông não vụ delegate với, em đọc cũng không hiểu cách dùng của nó
Bạn cứ hiểu nôm na là bạn gán một method thay thế cho một method delegate. Ví dụ cụ thể là bạn muốn khi một luồng xử lý ở Class A call một method của class B.
Class A
{
public delegate void OnExecute(int a);
public void Execute()
{
int b = 10;
if(OnExecute != null) OnExecute(b);
}
}
Class B
{
public void OnExecute(int a)
{
Console.Writeline("Hello {0}", a);
}
}
Class Main
{
public void Start()
{
A a = new A();
a.OnExecute = (new B()).OnExecute
a.Execute();
}
}
// output: 10
Ở ví dụ trên class B muốn lấy một kết quả tính toán của A để tính toán. Tuy nhiên ta ko muốn xen ngang luồng xử lý Execute() của A để lấy kết quả b = 10 ra cho B rồi mới làm việc khác, thế là delegate ra đời cho phép method OnExecute() của B xen ngang trong luồng xử lý của A cũng như lấy được biến b=10 ra.
Nói chung đó là khái niệm cơ bản nhất của delegate, còn thực tế sử dụng thì rất nhiều case nữa.
thím dreamnight giải thích việc so sánh C# anonymous type là chuẩn xác và cô đọng rồi.
còn về delegate, nếu search gg thì hay đc gọi là "con trỏ hàm", bạn có thể hiểu nó là 1 kiểu định nghĩa dữ liệu để lưu trữ và trao đổi thông tin về "hàm" (function), rồi sau đó sử dụng cho các thành phần khác. Hàm cũng có thể được lưu trữ, trao đổi và truyền đi như những dữ liệu khác (int, string, object...). Các thành phần khác muốn sử dụng delegate thì chỉ cần biết input type/ouput type của delegate, giống như biết 1 hàm có đầu vào là 2 số nguyên, đầu ra là 1 số nguyên, ko cần biết bên trong định nghĩa hàm là gì. Biết được kiểu đầu vào/đầu ra là có thể trao đổi hoặc sử dụng hàm đó.
1 hàm truyền vào 1 hàm khác, VD trong toán học, f(g(x)), trong thực tế đôi khi chả cần biết hàm g() bên trong nó làm cái gì, chỉ cần biết nó có đầu vào kiểu gì và đầu ra kiểu gì, thế thì người ta thiết kế ra 1 kiểu dữ liệu để truyền định nghĩa hàm g() đó vào trong hàm f(), sử dụng cái thông tin về hàm g() đấy để là phần tử trong phép tính của hàm f().
toi_yeu_quyen
17-02-2020, 13:02
Cảm ơn các bác cái linq em hiểu rõ rồi còn cái delegate chắc em phải tìm hiểu thêm về nó vậy, đọc xong em vẫn chưa hiểu lắm, delegate có cách viết tương ứng nào trong java không các bác nhỉ?
dreamnight
17-02-2020, 14:23
Cảm ơn các bác cái linq em hiểu rõ rồi còn cái delegate chắc em phải tìm hiểu thêm về nó vậy, đọc xong em vẫn chưa hiểu lắm, delegate có cách viết tương ứng nào trong java không các bác nhỉ?
Delegate keyword là cách dùng triển khai con trỏ hàm của riêng C# tạo ra để nhằm tối ưu source code (viết gọn hơn, dễ hiểu để triển khai hơn). Hiện tại java vẫn chưa hỗ trợ nó, tuy nhiên trong Gang of Four thì có Interpreter pattern là một cách áp dụng của delegate method. Nếu bạn hiểu Interpreter thì Delegate method nó cũng dạng như thế :stick:
haylachoi
18-02-2020, 09:35
Đơn giản thì cứ coi delegate là từ khóa để định nghĩa 1 kiểu dữ liệu đi.
Định nghĩa kiểu dữ liệu A.
class A{}
Định nghĩa kiểu dữ liệu B (chấp nhận bất cứ hàm nào có kiểu trả về là void và ko có tham số).
delegate void B();
Khai báo biến
A a;
B b;
Muốn gán giá trị cho biến a thì phải tạo 1 thể hiện của class A.
a= new A();
Muốn gán giá trị cho biến b thì phải tạo 1 hàm void ko tham số.
b= delegate(){};
// hoặc
b= ()=>{};
// hoặc
void function(){}
b= function;
vBulletin® v3.8.0, Copyright ©2000-2026, Jelsoft Enterprises Ltd.