如何将接口用作“out”参数
本文关键字:out 参数 接口 | 更新日期: 2023-09-27 18:30:18
public interface IAnimal
{
}
public interface IDog : IAnimal
{
}
public class Dog : IDog
{
public bool has_two_legs = false;
}
public static class test
{
public static void QueryAnimalProperties(out IAnimal animal_details)
{
//some sql queries
animal_details.has_two_legs = true;
}
public static void Test()
{
Dog my_dog;
test.QueryAnimalProperties(out my_dog);
}
}
当我尝试使用"out"关键字调用函数传递和狗类的实例时,我收到错误:
"方法的最佳过载...有一些无效的参数"
我如何能够将实现接口的类传递给我的数据库函数以填充数据?
更新:
test.QueryAnimalProperties(out (IAnimal)my_dog);
尝试类型转换输入也会给出错误:
引用或 out 参数必须是可赋值变量
QueryAnimalProperties
可以返回一个IAnimal
的对象,但不能返回IDog
的对象(例如 ICat
)。此类对象不可分配给IDog
变量。因此,这是禁止的。
你不需要 out 参数。
但是,如果要使用它,请使用具有约束的泛型方法。
public interface IAnimal
{
string Name { get; set; }
}
public interface IDog : IAnimal
{
}
public void QueryAnimalProperties<T>(out T animal)
where T : IAnimal, new()
{
animal = new T();
animal.Name = "Fred";
}
public class Dog : IDog
{
public string Name { get; set; }
}
void Main()
{
Dog dog;
QueryAnimalProperties(out dog);
Console.WriteLine(dog.Name);
}
请注意,如果在不修改其余代码的情况下删除 out 参数,则应用程序基本上取决于所谓的副作用,在这种情况下您希望避免这种情况。
http://codebetter.com/matthewpodwysocki/2008/04/30/side-effecting-functions-are-code-smells/
没有理由在这里使用 out
参数。
从方法中删除它,只需更新传递给它的类的属性(在IAnimal
接口中可用),如果这是您要执行的操作。
public void QueryAnimalProperties(IAnimal animal_details)
{
//some sql queries
animal_details.SomeAvailableProperty = "SomeValue";
}
由于该类已经是引用类型,因此当执行返回到名为 QueryAnimalProperties
的任何方法时,Dog
的实例将保留您在其中设置的值。
您不会将对象的实例作为out
参数的输入值传递,该值无论如何都会被丢弃。
这里有一个简单的反例,说明了为什么它不起作用:
public void QueryAnimalProperties(out IAnimal animal_details)
{
animal_details = new Hamster();
}
//
Dog dog;
QueryAnimalProperties(out dog);
在这种情况下,QueryAnimalProperties
的实现是有效的,因为 Hamster : IAnimal
和 animal_details
可以在实现接口时接受类型 Hamster
的对象。
但是QueryAnimalProperties
的调用方不能期望animal_details
最终解析为Dog
,如我的示例所示,它可能会将其设置为 Hamster
。
顺便说一句,我认为您没有正确使用out
:out
意味着引用本身已更改,就好像它是 C 和 C++ 中的指针值(或者由于这是一个堆对象,它将是指针到指针值)。
将out
参数视为等效于函数的返回类型,从中更改函数:
public void QueryAnimalProperties(out IAnimal animal_details)
对此:
public IAnimal QueryAnimalProperties()
Dog dog = QueryAnimalProperties(); // invalid, QueryAnimalProperties is not guaranteed to return Dog.
它的工作方式相同。
这失败了,因为Dog
是一个具体的类
public static void Test()
{
Dog my_dog; // <-- here
test.QueryAnimalProperties(out my_dog);
}
输出变量animal_details
public static void QueryAnimalProperties(out IAnimal animal_details)
只是承诺一个IAnimal
不一定是Dog
要解决此问题,请将类型从Dog
编辑为IAnimal
:
public static void Test()
{
IAnimal my_dog; // <-- here
test.QueryAnimalProperties(out my_dog);
}