我有很多类,它们共享很多属性,并且有很多通用接口。我经常想用另一个对象的数据构建一个对象,而它们共享一个接口。为了更容易,我有一个巧妙的小方法:
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.....
}
现在rider抱怨不可为null的属性未初始化,这是有道理的。我知道它们已经初始化,但对于IDE来说,这很难看到,我得到了编译。这让我很失望,因为我认为这是一个潜在的错误,每次我都必须思考是否有什么问题。有没有一种替代我的方法的方法不会发生这种情况?
好的,到目前为止我还没有得到答案。这不可能吗?这不是一个正常的用例吗?net5有可能吗?
编译器警告:
C:MyFilePathMyClass.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:MyFilePathMyProject.csproj]
它告诉我也许可以使属性为null,这是我绝对不想要的。
编译器和分析器通常(或很容易(无法解释反射代码,因此在它们的赋值和可为空性方面相当不可信。如果您知道编译器无法验证的内容是正确的:只需通过#pragma
、受影响代码上的[SuppressMessage(...)]
或抑制文件(只是另一个文件中的[assembly:SuppressMessage(...)]
,用Target
告诉编译器它适用于什么(在特定代码块上添加警告抑制。Rider可能有一些其他方式可以通过上下文菜单来抑制消息。
注意:如果你走这条路,你可能还想添加断言——尤其是在DEBUG
构建中——你认为是真的:实际上是真的。
如果您使用的是C#9,则可以添加少量dammit(!
(标记,或者关闭该代码的可空性检查。
是的,在我看来,这并不是一个完美优雅的解决方案。以下是我能想到的一些解决方案,按照优雅的顺序:
1.快速;冲击力
只要告诉骑手不要用#pragma声明来抱怨它,我相信在你的情况下应该是这样的:
#pragma warning disable CS8618
[code that throws the warning]
#pragma warning restore CS8618
2.编写代码生成代码
编写一个小型应用程序,提取这些通用接口,为每个自动生成设定值代码
3.不要将数据与控制代码混合
如果需要在具有不同控制器的类(即类(上设置数据,请将其放入自己的数据类中。Tadaaa,您刚刚获得了设置公共值的类继承能力。