Specify that an interface can only be implemented by reference types C#
If I declare an interface in C#, is there any way I can explicitly declare that any type implementing that interface is a reference type?
The reason I want to do this is so that wherever I use the interface as a type parameter, I don't have to specify that the implementing type also has to be a reference type.
Example of what I want to accomplish:
public interface IInterface
{
void A();
int B { get; }
}
public class UsingType<T> where T : IInterface
{
public void DoSomething(T input)
{
SomeClass.AnotherRoutine(input);
}
}
public class SomeClass
{
public static void AnotherRoutine<T>(T input)
where T : class
{
// Do whatever...
}
}
As the argument to SomeClass.AnotherRoutine()
is required to be a reference type, I will here get a compiler error where I call the method, suggesting that I force T
to be a reference type ( where T : IInterface, class
in the declaration of UsingType
). Is there any way I can enforce this already at the interface level?
public interface IInterface : class
doesn't work (obviously) but maybe there's another way to accomplish the same thing?
If you are passing something around under an interface, then even if you have a value type implementing that interface it will become boxed if cast to the interface and behave like a reference type (because it is boxed inside a reference type).
interface IFoo {
int Value { get; set; }
}
struct Foo : IFoo {
public int Value { get; set; }
}
Observe the effects when used as a value type:
var a = new Foo() { Value = 3 };
var b = a; // copies value
b.Value = 4;
Console.WriteLine( "a has {0}", a.Value ); //output: a has 3
Console.WriteLine( "b has {0}", b.Value ); //output: b has 4
Now look what happens when you cast it to the interface:
var a = new Foo() { Value = 3 } as IFoo; //boxed
var b = a; // copies reference
b.Value = 4;
Console.WriteLine( "a has {0}", a.Value ); //output: a has 4
Console.WriteLine( "b has {0}", b.Value ); //output: b has 4
So it doesn't matter whether a struct or class implements the interface. If cast to the interface and then is passed around under the interface, then it will behave as a reference type.
Edit : So if these are your requirements...
For contract X:
Well, you're simply stuck then, because those contradict each other.
Using the constraint where T: class, IFoo
wouldn't even work all the time. If I had this method (based on the same Foo
and IFoo
above):
static void DoSomething<T>(T foo) where T: class, IFoo {
foo.Value += 1;
Console.WriteLine( "foo has {0}", foo.Value );
}
Then it would throw a compile error under this circumstance:
var a = new Foo(){ Value = 3 };
DoSomething(a);
But it would work just fine under this circumstance:
var a = new Foo(){ Value = 3} as IFoo; //boxed
DoSomething(a);
So as far as I'm concerned, use where T: class, IFoo
-style constraint, and then it may not matter if a struct implements the interface as long as it is boxed. Depends on what checking EF does if passed a boxed struct, though. Maybe it will work.
If it doesn't work, at least the generic constraint gets you part-way there, and you can check foo.GetType().IsValueType
(referring to my DoSomething
method above) and throw an ArgumentException
to handle the case of boxed structs.
http://msdn.microsoft.com/en-us/library/d5x73970.aspx. Looks like you can specify it's a "class", which means reference type.
i dont think you can restrict interfaces in that way unfortunatly. According to msdn interfaces can be implemented by any type, both structs and classes :/
链接地址: http://www.djcxy.com/p/7596.html下一篇: 指定一个接口只能通过引用类型实现C#