C#泛型中的类特定函数-可观察到的轻微mod-to-UWP模板
我正在使用最新的UWP(和Windows Template Studio)方法构建一个应用程序。有一个聪明的班叫。 所以,这只是背景。我想修改第13行上的条件,以便Double的可忽略更改不会标记属性更改。所以,我扩充了第13行并创建了一个名为NegligibleChange的新函数C#泛型中的类特定函数-可观察到的轻微mod-to-UWP模板,c#,generics,uwp,windows-template-studio,C#,Generics,Uwp,Windows Template Studio,我正在使用最新的UWP(和Windows Template Studio)方法构建一个应用程序。有一个聪明的班叫。 所以,这只是背景。我想修改第13行上的条件,以便Double的可忽略更改不会标记属性更改。所以,我扩充了第13行并创建了一个名为NegligibleChange的新函数 protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null) {
protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if ((typeof(T) == typeof(double) && NegligibleChange(storage, value)) || Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
private bool NegligibleChange(double x, double y)
{
return Math.Abs(x - y) <= 1e-10;
}
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
受保护的无效集(ref T storage,T value,[CallerMemberName]string propertyName=null)
{
如果((typeof(T)=typeof(double)&&negiblechange(存储,值))| |等于(存储,值))
{
回来
}
储存=价值;
OnPropertyChanged(propertyName);
}
私有布尔可忽略更改(双x,双y)
{
返回Math.Abs(x-y)好吧,我对自己的问题有一个答案。你知道,泛型很难理解。如果以下不是处理这个问题的方法,请发表评论。需要的是添加一个非泛型版本的Set函数,该函数的输入签名为double。这样在运行时就没有附加条件了
protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
protected void Set(ref double storage, double value, [CallerMemberName]string propertyName = null)
{
if (NegligibleChange(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
private bool NegligibleChange(double x, double y)
{
return Math.Abs(x - y) <= 1e-10;
}
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
受保护的无效集(ref T storage,T value,[CallerMemberName]string propertyName=null)
{
if(等于(存储、值))
{
回来
}
储存=价值;
OnPropertyChanged(propertyName);
}
受保护的无效集(引用双存储,双值,[CallerMemberName]字符串propertyName=null)
{
if(可忽略的更改(存储、值))
{
回来
}
储存=价值;
OnPropertyChanged(propertyName);
}
私有布尔可忽略更改(双x,双y)
{
return Math.Abs(x-y)提问者发布的答案通常被认为是正确的方法。当你有一个泛型方法,它必须为一个特定类型做一些特殊的事情时,它不再是泛型的
“首先,实际问题从来没有得到回答,第二,关于这个方法要考虑一些问题。
这不起作用,因为它说“不能将T转换为double”。有办法解决这个问题吗
是的,有几种方法可以做到这一点,其中一些方法比其他方法更好
首先,这通常是一种糟糕的类型测试方法
typeof(T) == typeof(double)
您手头有两个Ts,因此您可以这样做:
protected void Set<T>(ref T storage, T value, blah blah blah)
{
if (Equals(storage, value))
return;
double? oldValue = storage as double?;
double? newValue = value as double?;
if (oldValue != null && newValue != null && Negligible(oldValue.Value, newValue.Value))
return;
...
将调用双版本,但是
Set<double>(ref someDouble, 1.23)
Set(参考1.23)
仍将调用通用版本。C#更喜欢非通用版本而不是通用版本,但如果您明确要求通用版本,您将得到它
类似地,如果从通用上下文调用您:
class C<T>
{
T storage;
void Frob(Blah blah, T value) {
blah.Set<T>(ref storage, value);
}
C类
{
T储存;
无效Frob(废话废话,T值){
blah.Set(参考存储、值);
}
然后C
不会调用您的特殊版本;同样,这会根据请求调用Set
所以要小心。强制转换参数。可忽略的更改((双)存储,(双)值)
不。这对我不起作用。无论强制转换是隐式的还是显式的,都会出现相同的错误:“error CS0030无法将类型“t”转换为“double”这是非常有用的信息,我将把它标记为答案。但是,我认为我将保留我在下面展示的方法,因为它的编译时间很快,并且我不太可能创建您在最后提到的函数层次结构。我理解您所说的两种方法的差异,但我认为它们编译到same结果-第一个只是第二个的简写。但是,我相信你更清楚。顺便说一下,第一个不是编译。它需要在第一个双精度后加“?”。(我不能添加,因为stackoverflow不允许少于6个字符的修订。
Set<double>(ref someDouble, 1.23)
class C<T>
{
T storage;
void Frob(Blah blah, T value) {
blah.Set<T>(ref storage, value);
}