如何使用两个相同的类名称和具有不同返回类型的相同辅助方法来重构此代码?
我有下面的两个类别:
public async A GernerateStuff(int expireDays = 15)
{
using var randomNumberGenerator = RandomNumberGenerator.Create();
var randomBytes = new byte[64];
var now = DateTime.UtcNow;
randomNumberGenerator.GetBytes(randomBytes);
return new A
{
Stuff = Convert.ToBase64String(randomBytes),
Created = now,
Expires = now.AddDays(expireDays)
};
}
public async B GernerateStuff(int expireDays = 10)
{
using var randomNumberGenerator = RandomNumberGenerator.Create();
var randomBytes = new byte[64];
var now = DateTime.UtcNow;
randomNumberGenerator.GetBytes(randomBytes);
return new B
{
Stuff = Convert.ToBase64String(randomBytes),
Created = now,
Expires = now.AddDays(expireDays)
};
}
public class A
{
public string Stuff{ get; set; }
public DateTime Created { get; set; }
public DateTime Expires { get; set; }
}
public class B
{
public string Stuff{ get; set; }
public DateTime Created { get; set; }
public DateTime Expires { get; set; }
}
约束是:我不能仅创建一个类,而不是两个单独的A和B类,因为它们在使用方面有显着差异。
现在,我的问题是:如何同时使用A和B类清洁此代码,而是一种用于gernerateStuff
的一种方法?
我可以创建一个这样的接口:
public class A : IInterface
{
}
public class B : IInterface
{
}
public interface IInterface
{
public string Stuff{ get; set; }
public DateTime Created { get; set; }
public DateTime Expires { get; set; }
}
然后,问题是public async iinterface gernerateStuff(int expiredays = 15)
签名如何处理A和B类?
I have two classes like below:
public async A GernerateStuff(int expireDays = 15)
{
using var randomNumberGenerator = RandomNumberGenerator.Create();
var randomBytes = new byte[64];
var now = DateTime.UtcNow;
randomNumberGenerator.GetBytes(randomBytes);
return new A
{
Stuff = Convert.ToBase64String(randomBytes),
Created = now,
Expires = now.AddDays(expireDays)
};
}
public async B GernerateStuff(int expireDays = 10)
{
using var randomNumberGenerator = RandomNumberGenerator.Create();
var randomBytes = new byte[64];
var now = DateTime.UtcNow;
randomNumberGenerator.GetBytes(randomBytes);
return new B
{
Stuff = Convert.ToBase64String(randomBytes),
Created = now,
Expires = now.AddDays(expireDays)
};
}
public class A
{
public string Stuff{ get; set; }
public DateTime Created { get; set; }
public DateTime Expires { get; set; }
}
public class B
{
public string Stuff{ get; set; }
public DateTime Created { get; set; }
public DateTime Expires { get; set; }
}
The constraint is: I can not create just one class instead of two separate classes A and B as they have significant differences in usage.
Now, my question is: how can I clean this code up having both classes A and B but a single method for GernerateStuff
?
I can create an interface like this:
public class A : IInterface
{
}
public class B : IInterface
{
}
public interface IInterface
{
public string Stuff{ get; set; }
public DateTime Created { get; set; }
public DateTime Expires { get; set; }
}
Then, the problem is how public async IInterface GernerateStuff(int expireDays = 15)
signature would handle both class A and B?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
TOT实现这一目标有几种方法。在其他答案中已经提到了一个,这是关于使用仿制药的。但是,这假设您的类型
a
和b
确实有任何共同点,您可以用作常见的通用约束,例如一个常见的基本接口。然后,您可以做到这一点:您还可以创建一个工厂,该工厂创建
a
或b
的实例,具体取决于某种条件 - 例如某些配置。但是,您还需要一个常见的基础接口:此解决方案具有优势,当您向工厂添加新类型时,您无需更改客户端逻辑。您需要更改的只是通过引入
新的C {...}
来更改工厂本身。此外,客户无法提供任何实际不起作用的类型,因为它们根本不提供任何类型的信息。顺便说一句,您的方法不会
等待
任何东西,因此没有理由将其制作async
。There are a couple of ways tot achieve this. One has already been mentioned in other answeres, which is about using generics. However this assumes your types
A
andB
do even have anything in common that you could use as common generic constraint - e.g a common base-interface. Then you could do this:You could also create a factory that creates the instances of
A
orB
depending on some condition - e.g. some configuration. However you'd also need a common base-interface for that:This solution has the advantage, that you don't need to change the client-logic when you add a new type to the factory. All you need to change is the factory itself by introducing
new C { ... }
. Furthermor a client cannot provide any types that actually don't work, as they don't provide any type-information at all.By the way your method does not
await
anything, so there's no reason to make itasync
.创建静态出厂方法并将其注入参数:
但是,如果A类和B类是相同的,为什么不使用同一类呢?这是一种确定的代码气味,您可能应该考虑如何对问题进行建模。另外,
async
在没有等待的情况下不会有任何意义,因此请摆脱它。Create a static factory method and inject it as a parameter:
But if class A and B are identical, why not use the same class? This is a definite code smell, and you should probably think about how you model your problem some more. Also,
async
does not serve any point without an await, so get rid of it.我在聚会上有点迟了,但是您可以将词典与代表使用可以提供懒惰初始化的代表。
让我举个例子。首先,我们需要进行枚举以避免
在创建类实例时else
语句:然后,我们需要拥有所有派生类具有相同行为的抽象基类:
而派生的类看起来像这样。 :
然后,工厂看起来像这样,您可以根据需要自定义任何属性或方法:
您可以这样使用:
I am little bit late at the party, however you can use dictionary with delegates which can provide lazy initialization.
Let me show an example. At first, we need to make enums to avoid
if else
statements while creating instances of classes:Then we need to have abstract base class which has the same behaviour for all derived classes:
And derived classes look like this:
Then Factory looks like this and you can customize any property or method if you want to:
And you can use it like this: