如何通过接口设置属性而不得到编译器警告
How to set Properties by Interface and not get compilerwarnings
我有很多 类 共享很多属性并且有很多通用接口。
我想用来自另一个对象的数据构造一个对象并且它们共享一个接口的情况经常发生。为了让这更容易,我有这个巧妙的小方法:
public static List<PropertyInfo> InterfaceProperties(Type type)
{
return new[] {type}
.Concat(type.GetInterfaces())
.SelectMany(i => i.GetProperties(BindingFlags.Instance | BindingFlags.Public)).ToList();
}
public static void SetFromSimilar<TInterface>(TInterface destination,TInterface source)
{
var properties = InterfaceProperties(typeof(TInterface));
foreach (var property in properties)
{
var val = property.GetValue(source, null);
property.SetValue(destination, val, null);
}
}
效果棒极了,因为现在我可以做到了:
public class MyClass: IMyInterface
{
public MyClass(IMyInterface otherClass)
{
SetFromSimilar(this,otherClass)
}
....MyProperties.....
}
现在骑手抱怨不可为空的属性未初始化,这是有道理的。我知道它们已初始化,但对于很难看到的 IDE,我得到了编译器警告。这让我失望,因为我看到它被标记为一个潜在的错误,我每次都必须考虑是否有问题。
有没有替代方法可以避免这种情况?
好的,到目前为止我没有得到任何答案。不可能吗?这不是一个正常的用例吗? net5 是否有可能?
编译器警告:
C:\My\File\Path\MyClass.cs(10,16): warning CS8618: Non-Nullable-Eigenschaft "MyProperty" muss beim Beenden des Konstruktors einen Wert ungleich NULL enthalten.
Erwägen Sie eine Deklaration von "Eigenschaft" als Nullable. [C:\My\File\Path\MyProject.csproj]
它告诉我可以使 属性 可为空,我绝对不想要。
编译器和分析器通常不能(或轻易地)解释反射代码,因此对于它们的赋值和可空性,有理由不相信。如果您知道编译器无法验证的某些内容是正确的:只需通过 #pragma
、受影响代码上的 [SuppressMessage(...)]
或抑制文件(这只是 [assembly:SuppressMessage(...)]
在不同的文件中, Target
告诉编译器它适用于什么)。通过上下文菜单,Rider 可能有其他一些抑制消息的方法。
注意:如果你走这条路,你可能还想添加断言 - 特别是在 DEBUG
构建中 - 你认为是真的:实际上是真的。
如果您使用的是 C# 9,您可以添加一些该死的 (!
) 标记,或者关闭该代码的可空性检查。
嗯,是的,在我看来,这看起来不是解决您的问题的完美方案。以下是我能想到的一些解决方案,按优雅顺序排列:
1.快速 & 蛮力
只是告诉骑手不要用#pragma 语句抱怨它,我相信你的情况应该是这样的:
#pragma warning disable CS8618
[code that throws the warning]
#pragma warning restore CS8618
2。写代码生成代码
自己编写一个小应用程序,提取这些通用接口以自动为每个接口生成设置值代码
3。不要把数据和控制代码混在一起
如果需要在不同控制器的classes上设置数据,即classes,将其放入自己的数据class中。 Tadaaa,您刚刚获得了 class 继承设置公共值的能力。
我有很多 类 共享很多属性并且有很多通用接口。 我想用来自另一个对象的数据构造一个对象并且它们共享一个接口的情况经常发生。为了让这更容易,我有这个巧妙的小方法:
public static List<PropertyInfo> InterfaceProperties(Type type)
{
return new[] {type}
.Concat(type.GetInterfaces())
.SelectMany(i => i.GetProperties(BindingFlags.Instance | BindingFlags.Public)).ToList();
}
public static void SetFromSimilar<TInterface>(TInterface destination,TInterface source)
{
var properties = InterfaceProperties(typeof(TInterface));
foreach (var property in properties)
{
var val = property.GetValue(source, null);
property.SetValue(destination, val, null);
}
}
效果棒极了,因为现在我可以做到了:
public class MyClass: IMyInterface
{
public MyClass(IMyInterface otherClass)
{
SetFromSimilar(this,otherClass)
}
....MyProperties.....
}
现在骑手抱怨不可为空的属性未初始化,这是有道理的。我知道它们已初始化,但对于很难看到的 IDE,我得到了编译器警告。这让我失望,因为我看到它被标记为一个潜在的错误,我每次都必须考虑是否有问题。 有没有替代方法可以避免这种情况?
好的,到目前为止我没有得到任何答案。不可能吗?这不是一个正常的用例吗? net5 是否有可能?
编译器警告:
C:\My\File\Path\MyClass.cs(10,16): warning CS8618: Non-Nullable-Eigenschaft "MyProperty" muss beim Beenden des Konstruktors einen Wert ungleich NULL enthalten.
Erwägen Sie eine Deklaration von "Eigenschaft" als Nullable. [C:\My\File\Path\MyProject.csproj]
它告诉我可以使 属性 可为空,我绝对不想要。
编译器和分析器通常不能(或轻易地)解释反射代码,因此对于它们的赋值和可空性,有理由不相信。如果您知道编译器无法验证的某些内容是正确的:只需通过 #pragma
、受影响代码上的 [SuppressMessage(...)]
或抑制文件(这只是 [assembly:SuppressMessage(...)]
在不同的文件中, Target
告诉编译器它适用于什么)。通过上下文菜单,Rider 可能有其他一些抑制消息的方法。
注意:如果你走这条路,你可能还想添加断言 - 特别是在 DEBUG
构建中 - 你认为是真的:实际上是真的。
如果您使用的是 C# 9,您可以添加一些该死的 (!
) 标记,或者关闭该代码的可空性检查。
嗯,是的,在我看来,这看起来不是解决您的问题的完美方案。以下是我能想到的一些解决方案,按优雅顺序排列:
1.快速 & 蛮力
只是告诉骑手不要用#pragma 语句抱怨它,我相信你的情况应该是这样的:
#pragma warning disable CS8618
[code that throws the warning]
#pragma warning restore CS8618
2。写代码生成代码
自己编写一个小应用程序,提取这些通用接口以自动为每个接口生成设置值代码
3。不要把数据和控制代码混在一起
如果需要在不同控制器的classes上设置数据,即classes,将其放入自己的数据class中。 Tadaaa,您刚刚获得了 class 继承设置公共值的能力。