[英]How can I use an interface as an “out” parameter?
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);
}
}
When I try to call the function passing and instance of the dog class with the " out " keyword I am receiving an error: 当我尝试使用“ out ”关键字调用函数传递和dog类的实例时,收到错误消息:
"The best overload for method ... has some invalid arguments"
“方法的最佳重载...具有一些无效的参数”
How am I able to pass a class which implements an interface to my database function to be filled with data? 我如何传递一个实现接口的类到我的数据库函数以填充数据?
UPDATE: 更新:
test.QueryAnimalProperties(out (IAnimal)my_dog);
Trying to type cast the input also gives an error: 尝试类型转换输入也会产生错误:
A ref or out argument must be an assignable variable
ref或out参数必须是可分配的变量
QueryAnimalProperties
could return an object that is IAnimal
, but not IDog
(eg ICat
). QueryAnimalProperties
可以返回IAnimal
而不是IDog
的对象(例如ICat
)。 Such an object would not be assignable to an IDog
variable. 这样的对象将不能分配给
IDog
变量。 Therefore, this is forbidden. 因此,这是禁止的。
You don't need an out parameter. 您不需要out参数。
But if you want to use it, then use a Generic Method with constraints. 但是,如果要使用它,请使用带有约束的通用方法。
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);
}
Note that if you remove the out parameter without modifying the rest of your code, then your application basically depends on what is known as side-effect, which is something you want to avoid in this situation. 请注意,如果在不修改其余代码的情况下删除out参数,则您的应用程序基本上取决于所谓的副作用,在这种情况下,您需要避免这种情况。
http://codebetter.com/matthewpodwysocki/2008/04/30/side-effecting-functions-are-code-smells/ http://codebetter.com/matthewpodwysocki/2008/04/30/side-effecting-functions-are-code-smells/
There's no reason to use the out
parameter here. 这里没有理由使用
out
参数。
Remove it from your method, and just update the properties of the class you pass to it (that are available in the IAnimal
interface), if that's what you're intending to do. 如果您打算这样做,则将其从方法中删除,然后仅更新传递给它的类的属性(可在
IAnimal
接口中使用)。
public void QueryAnimalProperties(IAnimal animal_details)
{
//some sql queries
animal_details.SomeAvailableProperty = "SomeValue";
}
Because the class is already a reference type, when execution returns to whatever method called QueryAnimalProperties
, your instance of Dog
will retain the values you set in it. 因为该类已经是引用类型,所以当执行返回到称为
QueryAnimalProperties
任何方法时, Dog
的实例将保留在其中设置的值。
You don't pass an instance of an object as an input value for an out
parameter, the value will be discarded anyway. 您不会将对象的实例作为
out
参数的输入值传递,无论如何该值都将被丢弃。
Here's a simple counter-example that demonstrates why it doesn't work: 这是一个简单的反例,演示了为什么它不起作用:
public void QueryAnimalProperties(out IAnimal animal_details)
{
animal_details = new Hamster();
}
// //
Dog dog;
QueryAnimalProperties(out dog);
In this case, the implementation of QueryAnimalProperties
is valid because Hamster : IAnimal
and animal_details
can accept an object of type Hamster
as it implements the interface. 在这种情况下,
QueryAnimalProperties
的实现是有效的,因为Hamster : IAnimal
和animal_details
在实现接口时可以接受Hamster
类型的对象。
But the caller of QueryAnimalProperties
cannot expect animal_details
to ultimately resolve as Dog
, as my example shows, it might set it to Hamster
. 但是
QueryAnimalProperties
的调用者不能期望animal_details
最终像Dog
那样解析,如我的示例所示,它可能会将其设置为Hamster
。
As an aside, I don't think you're using out
correctly: out
means that the reference itself is changed, as though it were a pointer-to value in C and C++ (or as this is a heap object, it would be pointer-to-pointer value). 顺便说一句,我认为您使用的方式
out
正确: out
表示引用本身已更改,就好像它是C和C ++中的指向指针的值一样(或者因为这是一个堆对象,所以它将是指针到指针的值)。
Consider out
params as equivalent to the return-type of the function, change your function from this: 考虑
out
PARAMS等同于返回类型的功能,你的函数从:
public void QueryAnimalProperties(out IAnimal animal_details)
to this: 对此:
public IAnimal QueryAnimalProperties()
Dog dog = QueryAnimalProperties(); // invalid, QueryAnimalProperties is not guaranteed to return Dog.
and it works the same way. 它以相同的方式工作。
This fails becuase Dog
is a concrete class 这是因为
Dog
是一个具体的类
public static void Test()
{
Dog my_dog; // <-- here
test.QueryAnimalProperties(out my_dog);
}
The out variable animal_details
in 输出变量
animal_details
in
public static void QueryAnimalProperties(out IAnimal animal_details)
just promises an IAnimal
not necessarily a Dog
只是承诺
IAnimal
不一定是Dog
To fix this edit the type from Dog
to IAnimal
: 要解决此问题,请从
Dog
到IAnimal
修改类型:
public static void Test()
{
IAnimal my_dog; // <-- here
test.QueryAnimalProperties(out my_dog);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.