我们有一个与通用客户(金/银)的接口,现在我可以说我存储了最后一个创建的cutomer(Cache / DB / etc)。
如何创建返回客户类型的GetCustomer方法。 我应该将GetCustomer添加到基类或接口或其他地方吗?以及我们如何使用GetCustomer?
希望这是有道理的。
interface ICstomerInterface<T>
{
T MakeCustomer();
}
public abstract class BaseCustomer<T>: ICstomerInterface<T>
{
public string Type { get; set; }
public string Name { get; set; }
// methods
public abstract T MakeCustomer();
}
public class Gold : BaseCustomer<Gold>
{
public override Gold MakeCustomer()
{
var customer = new Gold
{
Type= "Gold",
Name = "Jack"
};
return customer;
}
}
public class Silver : BaseCustomer<Silver>
{
public override Silver MakeCustomer()
{
var customer = new Silver();
customer.Name = "Jones";
customer.Type = "Silver";
return customer;
}
}
答案 0 :(得分:0)
您可以使用扩展方法获取客户类型(在静态类上):
public static Type GetCustomerType<T>(this ICstomerInterface<T> _customer)
{
return typeof(T);
}
所有这些都意味着每次创建实现该接口的新Customer类时都不必创建冗余代码。
答案 1 :(得分:0)
您似乎正在尝试使用经典Factory Method。
对于简单的类,就像你要问的那样,我会在基类上添加一个静态方法,如下所示:
public abstract class BaseCustomer<T>: ICstomerInterface<T>
{
public static BaseCustomer<T> GetLastCustomer()
{
// Get from storage, the last customer.
}
}
这样,您的创建客户方法与您的获取客户方法是分开的,但仍可从任何地方访问。
答案 2 :(得分:0)
您的示例代码不包含可以包含所有客户的基本类型,即没有强类型变量可以包含BaseCustomer<Gold>
或BaseCustomer<Silver>
。这两者之间没有类型兼容性,只有Dictionary<int>
可以存储为Dictionary<string>
(事实上,更糟糕的是,因为对象模型中没有协方差) 。鉴于这一事实,您的问题没有多大意义,因为您总是必须声明类型参数以在某处存储客户,因此无需在运行时学习该类型。
但是,让我们说你想要一个适合两者的缓存。您将引入一个非通用的基本接口:
public interface ICustomer
{
Guid CustomerGuid { get; }
}
public abstract class BaseCustomer<T>: ICstomerInterface<T>, ICustomer
{
///etc....
现在您可以定义一个可以容纳所有客户的缓存:
var cache = new Dictionary<Guid,ICustomer>();
var gold = new Gold();
cache.Add( gold.CustomerGuid, gold );
var silver = new Silver();
cache.Add( silver.CustomerGuid, silver );
现在您可以通过其Guid检索任何客户:
var customer = cache[guid];
要确定其类型,只需使用
即可bool isGold = customer is Gold;
bool isSilver = customer is Silver;
或者获取一个告诉你类型的字符串:
string type = customer.GetType().Name;
答案 3 :(得分:0)
您设计的问题是MakeCustomer
是客户的实例方法。这意味着您必须创建一个客户才能调用MakeCustomer
。换句话说,这种设计不起作用!
您有两种选择:只需在各自的构造函数中初始化客户,或者创建客户工厂。这必须是一个单独的类(静态或非静态)。
泛型类型参数是多余的。
public abstract class CustomerBase
{
public CustomerBase(string name)
{
Name = name;
}
public abstract string Type { get; }
public string Name { get; }
}
public class GoldCustomer : CustomerBase
{
public GoldCustomer(string name)
: base(name)
{
}
public override string Type => "Gold";
}
public class SilverCustomer : CustomerBase
{
public SilverCustomer(string name)
: base(name)
{
}
public override string Type => "Silver";
}
Type
属性可以是仅限getter的属性。它可以在基类中抽象,以强制具体的客户类来实现它。
必须将名称传递给构造函数才能为不同的客户分配不同的名称。
另请参阅维基百科上的Abstract factory pattern。
示例:
var customers = new List<CustomerBase> {
new GoldCustomer("Frank"),
new SilverCustomer("Jack")
};
foreach (CustomerBase c in customers) {
Console.WriteLine($"{c.Name} is {c.Type}");
}
打印:
弗兰克是金子 杰克是银色的