C# 安全及;C中显式接口成员的简单访问#
当我在C#中使用显式接口实现时,常常需要将对象强制转换到其接口之一,以便访问该接口的成员。由于编译时类型检查提供了更高的可靠性和可维护性,我一直倾向于使用隐式转换来执行此操作。我所知道的唯一方法是使用两行代码,并在作用域中引入另一个变量。以下是一个例子:C# 安全及;C中显式接口成员的简单访问#,c#,interface,casting,implicit-conversion,C#,Interface,Casting,Implicit Conversion,当我在C#中使用显式接口实现时,常常需要将对象强制转换到其接口之一,以便访问该接口的成员。由于编译时类型检查提供了更高的可靠性和可维护性,我一直倾向于使用隐式转换来执行此操作。我所知道的唯一方法是使用两行代码,并在作用域中引入另一个变量。以下是一个例子: public interface IMyType { string SayHello(); } public class MyType : IMyType { string IMyType.SayHello() { retur
public interface IMyType
{
string SayHello();
}
public class MyType : IMyType
{
string IMyType.SayHello() { return "Hello!"; }
}
class Program
{
static void Main(string[] args)
{
var item = new MyType();
// Option 1 - Implicit cast. Compile time checked but takes two lines.
IMyType item2 = item;
System.Console.WriteLine(item2.SayHello());
// Option 2 - One line but risks an InvalidCastException at runtime if MyType changes.
System.Console.WriteLine(((IMyType)item).SayHello());
// Option 3 - One line but risks a NullReferenceException at runtime if MyType changes.
System.Console.WriteLine((item as IMyType).SayHello());
}
}
因为编译器知道MyType
实现了IMyType
,我假设隐式强制转换比显式强制转换好,因为稍后对MyType
声明的更改将导致编译错误,而不是运行时的InvalidCastException
。然而,我有点喜欢显式cast语法的简单性,并且经常在其他人的代码中看到它的使用
我的问题有三个:
- 您更喜欢以上哪种选择(以及为什么)
- 有更好的方法吗
- 当可以进行隐式转换时,关于执行显式转换的最佳实践是什么
var IMyType item3 = item as MyConcreteType;
if(item3 != null) {
item3.SayHello();
}
我通常喜欢这样:
class Program
{
static void Main(string[] args)
{
var item = new MyType();
if( item is IMyType ){
Console.WriteLine( (item as IMyType).SayHello() );
}
else { /* Do something here... */ }
}
}
如果不确定该对象是否是接口的实例,则执行as/null检查。通常,您从方法/函数调用返回接口,在这种情况下,您只需将其存储在一个变量中而不需要转换(尽管可能仍需要空检查)。这里有一个编译时检查的行:
public static class Converter
{
public static T ReturnAs<T>(T item)
{
return item;
}
}
class Program
{
static void Main(string[] args)
{
var item = new MyType();
// Option 1 - Implicit cast. Compile time checked but takes two lines.
IMyType item2 = item;
System.Console.WriteLine(item2.SayHello());
// Option 2 - One line but risks an InvalidCastException at runtime if MyType changes.
System.Console.WriteLine(((IMyType)item).SayHello());
// Option 3 - One line but risks a NullReferenceException at runtime if MyType changes.
System.Console.WriteLine((item as IMyType).SayHello());
// Option 4 - compile time one liner
Converter.ReturnAs<IMyType>(item).SayHello();
}
}
公共静态类转换器
{
公共静态T返回(T项)
{
退货项目;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var item=new MyType();
//选项1-隐式转换。编译时已选中,但需要两行。
IMyType item2=项目;
System.Console.WriteLine(item2.SayHello());
//选项2-一行,但如果MyType更改,则在运行时可能出现InvalidCastException。
System.Console.WriteLine(((IMyType)item.SayHello());
//选项3-一行,但如果MyType更改,则在运行时可能出现NullReferenceException。
System.Console.WriteLine((项作为IMyType.SayHello());
//选项4-编译时一行程序
Converter.ReturnAs(item.SayHello();
}
}
您不必要地应用了两次强制转换。您应该先执行“as”,然后简单地执行空检查。+1我同意将隐式强制转换作为一般规则。我认为它更优雅。