Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 安全及;C中显式接口成员的简单访问#_C#_Interface_Casting_Implicit Conversion - Fatal编程技术网

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

当我在C#中使用显式接口实现时,常常需要将对象强制转换到其接口之一,以便访问该接口的成员。由于编译时类型检查提供了更高的可靠性和可维护性,我一直倾向于使用隐式转换来执行此操作。我所知道的唯一方法是使用两行代码,并在作用域中引入另一个变量。以下是一个例子:

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我同意将隐式强制转换作为一般规则。我认为它更优雅。