我有这两个对象
class RNB
{
public RNB(double roomRate, double roomDays)
{
RoomRate = roomRate;
RoomDays = roomDays;
}
public double RoomRate { get; set; }
public double RoomDays { get; set; }
public const double BasicLimit = 100;
}
class HMS
{
public double Amount { get; set; }
public const double BasicLimit = 200;
}
然后我有这个方法:
public static double ComputeBasicAmount(double basicLimit, Func<double> multiplier)
{
return basicLimit * multiplier();
}
样本用法:
static void Main(string[] args)
{
RNB rnb = new RNB(100, 2);
double result = ComputeBasicAmount(RNB.BasicLimit, () => rnb.RoomDays * rnb.RoomRate);
Console.WriteLine("RNB Basic Amt: " + result.ToString());
HMS hms = new HMS() { Amount = 1000 };
result = ComputeBasicAmount(HMS.BasicLimit, () => hms.Amount);
Console.WriteLine("HMS Basic Amt: " + result.ToString());
Console.Read();
}
这里的问题,我想消除BasicLimit 的传递,因为我认为这看起来多余。是否可以将BasicLimit放在ComputeBasicAmount方法
中像这样......
public static double ComputeBasicAmount<T>(Func<T, double> multiplier, T obj)
{
return obj.BasicLimit * multiplier();
}
先谢谢你们......
PS:basicLimit不一定是CONST
答案 0 :(得分:0)
是的,你可以,但你必须首先检查obj
的类型,因为你不能将类型参数限制为特定的类。
这意味着您无法将ComputeBasicAmount
定义为仅ComputeBasicAmount<RNB>
和ComputeBasicAmount<HMS>
。
但是,您可以检查obj
是RNB
还是HMS
类型:
public static double ComputeBasicAmount<T>(Func<T, double> multiplier, T obj)
{
var cObj1 = obj as RNB;
if(cObj1!=null)
return cObj1.BasicLimit * multiplier();
var cObj2 = obj as HMS;
if(cObj2 != null)
return cObj1.BasicLimit * multiplier();
return null; //Or throw an exception, e.g. argument exception
}
答案 1 :(得分:0)
嗯,这个方法所做的就是多个两个双操作数。已经有了这方面的运营商。你不能简单地这样做:
RNB rnb = new RNB(100, 2);
double result = RNB.BasicLimit * rnb.RoomDays * rnb.RoomRate;
HMS hms = new HMS() { Amount = 1000 };
result = HMS.BasicLimit * hms.Amount;
答案 2 :(得分:0)
不,你不能这样做......即使你放入一个接口,你也不能指定一个实例方法必须是静态的,然后通过T
调用它。你必须使用反射,基本上...而且我认为远比明确指定房间限制更丑。您可能需要阅读我的proposal around static interfaces以获取更多信息。
就编译器而言,本质上你的两个BasicLimit
常量是不相关的。
由于您已经创建了房间的实例,可以拥有一个界面:
public interface IRoomType
{
double BasicLimit { get; }
}
然后将房间的实例传递给方法,并要求它以这种方式获取限制。这很难看,因为它使用实例成员来获取一个并非真正特定于任何特定实例的值,但这就是它的方式。
如果 要使用反射,您可能需要考虑在属性中指定限制而不是常量:
[BasicLimit(100)]
public class RNB { ... }
然后,您至少可以询问适用于T
的{{1}}类型,如果有的话。您不具备属性存在的编译时安全性,但将具有针对拼写错误的安全性,例如使一个常量BasicLimitAttribute
而不是{{1 }}
答案 3 :(得分:0)
这里可能更简单的答案是为类生成扩展方法,只需在没有任何参数的情况下调用ComputeBasicAmount
?
public static class ComputeBasicAmountEx
{
public static double ComputeBasicAmount(this RNB rnb)
{
return RNB.BasicLimit * rnb.RoomDays * rnb.RoomRate;
}
public static double ComputeBasicAmount(this HMS hms)
{
return HMS.BasicLimit * hms.Amount;
}
}
您的代码如下所示:
RNB rnb = new RNB(100, 2);
double result = rnb.ComputeBasicAmount();
Console.WriteLine("RNB Basic Amt: " + result.ToString());
HMS hms = new HMS() { Amount = 1000 };
result = hms.ComputeBasicAmount();
Console.WriteLine("HMS Basic Amt: " + result.ToString());
但是,我不认为这是最好的答案。我想我更喜欢创建一个接口并让类实现接口,但最终的代码看起来仍然一样。