类 有没有一种方法可以在不通过对象引用连接它们的情况下相互通信?
Is there a way for classes to communicate with one another without connecting them through object references?
我遇到的最困难的问题是说明问题。它可以运行,但感觉有一种更简洁的方法来实现同样的事情。有没有一种方法可以让一个 class 中的方法与另一个对象通信,而不必在 class 中创建对该对象的引用作为 属性?例如,这是一个非常简化的示例。我想创建一个存放宠物的庇护所对象。此外,我有一个 class 想要与收容所互动,可能会将宠物添加到收容所的宠物列表中。这只能通过引用遭遇对象上的避难所来实现吗?当我们需要一个对象与许多其他对象交互,或者许多对象与这个对象交互时,这感觉不太好扩展。
using System;
using System.Collections.Generic;
class Program
{
static Shelter shelter;
static Encounter encounter;
static void Main(string[] args)
{
// this is what I'd like to avoid
encounter = new Encounter();
encounter.shelter = shelter;
}
}
class Pet
{
string name;
public Pet()
{
name = "DefaultDog";
}
}
class Shelter
{
public List<Pet> pets;
public void AddPet(Pet pet)
{
pets.Add(pet);
}
}
class Encounter
{
// this is what I'd like to avoid
public Shelter shelter;
public void CapturePet()
{
shelter.AddPet(new Pet());
}
}
想法?
你的代码实际上是无效的——你必须创建一个 Encounter
class 的实例,它通常看起来像这样:
encounter = new Encounter();
这是你应该初始化和创建那个遭遇的地方。如果遭遇对避难所无效,则您必须提供避难所。在这种情况下,将它作为参数传递给构造函数是惯用的:
shelter = new Shelter();
encounter = new Encounter(shelter);
构造函数可能如下所示:
class Encounter
{
protected readonly Shelter _shelter;
public Encounter(Shelter shelter)
{
_shelter = shelter;
}
}
现在你的遭遇总是通过访问它自己的 _shelter
字段知道它与哪个避难所相关联。
回答您的问题 -- 是否有某种方法可以让您的 Shelter
自动找出 Encounter
的含义?答案是不。这是因为你可以拥有不止一处庇护所。
var shelters = new List<Shelter>();
shelters.Add(new Shelter());
shelters.Add(new Shelter());
var encounter = new Encounter(); //Which shelter is this associated with?
你必须告诉它是哪一个:
var shelters = new List<Shelter>();
shelters.Add(new Shelter());
shelters.Add(new Shelter());
var encounter = new Encounter(shelters[0]);
如果您使用委托,则无需在 Encounter class 中添加任何 class 引用即可实现您想要的结果。代表为您提供了必要的灵活性,可以根据需要将宠物添加到尽可能多的庇护所,以及任何其他类型的副作用。你可以在这里阅读更多关于它们的信息 https://docs.microsoft.com/en-us/dotnet/standard/events/
using System;
using System.Collections.Generic;
namespace SODelegate
{
class Program
{
static Shelter shelter = new();
static Shelter anotherShelter = new();
static Encounter encounter = new();
static void Main(string[] args)
{
encounter.OnCapturePet += delegate (object sender, EventArgs eventArgs)
{
Console.WriteLine("Running first delegate");
shelter.AddPet(new Pet());
};
encounter.OnCapturePet += delegate (object sender, EventArgs eventArgs)
{
Console.WriteLine("Running second delegate");
anotherShelter.AddPet(new Pet());
};
encounter.CapturePet();
}
}
class Pet
{
string name;
public Pet()
{
name = "DefaultDog";
}
}
class Shelter
{
public List<Pet> pets = new();
public void AddPet(Pet pet)
{
pets.Add(pet);
}
}
class Encounter
{
public event EventHandler OnCapturePet;
public void CapturePet()
{
Console.WriteLine("Running capture pet");
this.OnCapturePet(this, EventArgs.Empty);
}
}
}
我遇到的最困难的问题是说明问题。它可以运行,但感觉有一种更简洁的方法来实现同样的事情。有没有一种方法可以让一个 class 中的方法与另一个对象通信,而不必在 class 中创建对该对象的引用作为 属性?例如,这是一个非常简化的示例。我想创建一个存放宠物的庇护所对象。此外,我有一个 class 想要与收容所互动,可能会将宠物添加到收容所的宠物列表中。这只能通过引用遭遇对象上的避难所来实现吗?当我们需要一个对象与许多其他对象交互,或者许多对象与这个对象交互时,这感觉不太好扩展。
using System;
using System.Collections.Generic;
class Program
{
static Shelter shelter;
static Encounter encounter;
static void Main(string[] args)
{
// this is what I'd like to avoid
encounter = new Encounter();
encounter.shelter = shelter;
}
}
class Pet
{
string name;
public Pet()
{
name = "DefaultDog";
}
}
class Shelter
{
public List<Pet> pets;
public void AddPet(Pet pet)
{
pets.Add(pet);
}
}
class Encounter
{
// this is what I'd like to avoid
public Shelter shelter;
public void CapturePet()
{
shelter.AddPet(new Pet());
}
}
想法?
你的代码实际上是无效的——你必须创建一个 Encounter
class 的实例,它通常看起来像这样:
encounter = new Encounter();
这是你应该初始化和创建那个遭遇的地方。如果遭遇对避难所无效,则您必须提供避难所。在这种情况下,将它作为参数传递给构造函数是惯用的:
shelter = new Shelter();
encounter = new Encounter(shelter);
构造函数可能如下所示:
class Encounter
{
protected readonly Shelter _shelter;
public Encounter(Shelter shelter)
{
_shelter = shelter;
}
}
现在你的遭遇总是通过访问它自己的 _shelter
字段知道它与哪个避难所相关联。
回答您的问题 -- 是否有某种方法可以让您的 Shelter
自动找出 Encounter
的含义?答案是不。这是因为你可以拥有不止一处庇护所。
var shelters = new List<Shelter>();
shelters.Add(new Shelter());
shelters.Add(new Shelter());
var encounter = new Encounter(); //Which shelter is this associated with?
你必须告诉它是哪一个:
var shelters = new List<Shelter>();
shelters.Add(new Shelter());
shelters.Add(new Shelter());
var encounter = new Encounter(shelters[0]);
如果您使用委托,则无需在 Encounter class 中添加任何 class 引用即可实现您想要的结果。代表为您提供了必要的灵活性,可以根据需要将宠物添加到尽可能多的庇护所,以及任何其他类型的副作用。你可以在这里阅读更多关于它们的信息 https://docs.microsoft.com/en-us/dotnet/standard/events/
using System;
using System.Collections.Generic;
namespace SODelegate
{
class Program
{
static Shelter shelter = new();
static Shelter anotherShelter = new();
static Encounter encounter = new();
static void Main(string[] args)
{
encounter.OnCapturePet += delegate (object sender, EventArgs eventArgs)
{
Console.WriteLine("Running first delegate");
shelter.AddPet(new Pet());
};
encounter.OnCapturePet += delegate (object sender, EventArgs eventArgs)
{
Console.WriteLine("Running second delegate");
anotherShelter.AddPet(new Pet());
};
encounter.CapturePet();
}
}
class Pet
{
string name;
public Pet()
{
name = "DefaultDog";
}
}
class Shelter
{
public List<Pet> pets = new();
public void AddPet(Pet pet)
{
pets.Add(pet);
}
}
class Encounter
{
public event EventHandler OnCapturePet;
public void CapturePet()
{
Console.WriteLine("Running capture pet");
this.OnCapturePet(this, EventArgs.Empty);
}
}
}