I have the following code
var dataCollection;
if (ViewBag.WageType.ToLower() == "perm")
{
dataCollection = ViewBag.PermWageIndex;
}
else if(ViewBag.WageType.ToLower() == "trial")
{
dataCollection = ViewBag.TrialWageIndex;
}
The return type can be AbstractClass<Concrete1> or AbstractClass<Concrete2>. I must initialize the var at declaration. But, this means I lose the scope I desire. How can I modify this code to allow dynamic dataCollections without depending on the ViewBag?
You might be able to make AbstractClass<> implement the interface IAbstractClass and then make that the common type.
Whether this will work or not depends exactly which members the return type needs to access. Obviously, it won't be able to refer to any of the generically typed members, but that wouldn't make much sense anyway, since I'm assuming the consumer shouldn't know what the generic parameter is anyway.
The only way solving this is by providing a base class or interface which is inherited/implemented by Concrete1 and Concrete2 so you can declare dataCollection as AbstractClass<ISomething>.
Var is not dynamic typing it is resolved at compile time. Therefore you can not declare a variable without assignment (var x;) because the compiler can not infer the type.
You can fall back to object or dynamic however you loose any type safety if you do so.
Related
I got the error for the below code
public static Moq.Mock<T> CreateInstanceOfIMock<T>() {
return new Moq.Mock<T>();
}
I have solved the error it by using referred class type. See this below code
public static Moq.Mock<T> CreateInstanceOfIMock<T>() where T : class
{
return new Moq.Mock<T>();
}
Now I want to move this var mockColorsRepository = new Moq.Mock<IColorsRepository>(); code into common code by using generics. here IColorsRepository is an interface. So I made an interface reference for T instead of class like this below code
public static Moq.Mock<T> CreateInstanceOfIMock<T>() where T : interface
{
return new Moq.Mock<T>();
}
But am getting The type T must be a reference type in order to use it as parameter error. How can I refer interface instead of class to T. How can I achieve this?
class and struct in generic type constaints do not mean the same thing as the class and struct declarations that are used to declare class or struct types. Instead, they only restrict whether a generic type argument is a reference type (class), or a value type (struct).
So when you do where T : class you are not saying that T needs to be a class, you are saying that T needs to be a reference type. Similarly struct for value types.
Interfaces on their own do not have this property, so an interface can be implemented by both a reference type and a value type. As such, restricting your type to be of an interface does not really make sense there.
In your case, Moq requires you to pass a reference type, so you need to transitively carry over that type constraint in all your helper methods:
public static Moq.Mock<T> CreateInstanceOfIMock<T>()
where T : class
{
return new Moq.Mock<T>();
}
That’s all you need to do to create a mock of any valid type. You can use it with an interface using CreateInstanceOfIMock<IColorsRepository>() or any other type.
Of course, at that point, the method does not really make that much sense since it does not give you any benefit over just instantiating the mock yourself.
There's no generic constraint in C# to enforce that a type argument is an interface. But where T : class is really "where T is a reference type" - it includes interfaces.
If you wanted to enforce that T is an interface rather than a class, you could perform an execution-time check using typeof(T) within the method, but in this case it sounds like you don't really need to constrain it to be an interface.
I'm not sure that the "helper" method is particularly useful though - if you compare:
var mock = Helper.CreateInstanceOfIMock<Foo>();
and
var mock = new Moq.Mock<Foo>();
or even (unless you have Mock<T> as another type somewhere) just a using Moq; directive and
var mock = new Mock<T>();
The latter seems just as readable and shorter... it makes sense if you're going to add more logic in your method, but if it's only ever going to call the constructor, I don't think I'd bother with it.
I'm wondering if there is a way to do this inheritance situation in C#:
public class Item
{
public string Name { get; set; }
}
public class ItemExtended : Item
{
public int ExtendedProp { get; set; }
}
And let's say I have a method that returns objects of type Item:
public Item[] GetItems();
How can I make code like this run?
ItemExtended[] itemsExt = GetItems().Cast(i => (ExtendedItem)i).ToArray();
Where the cast wouldn't fail, the Name property value would be preserved and I would have an additional property ExtendedProp that I could access?
Edit (hopefully to clear some confusion)
In this situation the GetItems method would only ever return items of type Item. I was wondering if there was a casting method that could convert a base type to an inherited type such that all base member values are conserved (without the use of cloning).
If the runtime type of your object is Item, you can not cast it to an ItemExtended -- not unless there's a user-defined conversion that can create an ItemExtended from an Item. Note, however, that even then, you'll be creating a new instance of ItemExtended.
Inheritance in general doesn't work that way. In managed languages, downcasting only works if the runtime type of your object already is of the derived type. Instances of derived classes inherit all the data and behavior of their ancestor classes, but there's an ancestor doesn't have any knowledge of derived classes. Consider an example, where a derived class introduces a single new field. Firstly, the base class instance is smaller in size, so at the very least, a type cast would require allocating new memory. Second, you would have to decide between changing the runtime type of the original instance (which would be very weird indeed) or making a copy of the old data. The latter way would be very similar to the user-defined conversion scenario, except an user-defined conversion is explicitly invoked, and IMO better that way.
In unmanaged languages, you can of course make any arbitrary conversion you want -- but that just results in catastrophic failures if you do it wrong. In the example above, you would try to access the new field, but since it would not have been allocated for the instance, you would go beyond the boundaries of the object's memory space and access... whatever was in there, be it sensical or not.
If you want to introduce new behavior to existing classes, the C# way is via extension methods. Extension properties aren't there yet, and may never be, so you don't get the property syntax. You may or may not be able to live with that.
You may also find it interesting, that in XAML, the concept of attached properties sort of fits what you are trying to do: you can define arbitrary new properties for whatever -- but if you look at the implementation, what you are really doing is creating a dictionary that maps objects to their associated property values, and the XAML compiler sugarcoats this by making the markup look like you've added the properties to those objects.
You can use OfType instead of Cast:
ItemExtended[] itemsExt = GetItems().OfType<ItemExtended>().ToArray();
You're on the right track with a few adjustments,
use Select() instead of Cast() and
i as ItemExtended rather than (ItemExtended)i
This line should cast it correctly:
ItemExtended[] itemsExt = GetItems().Select(i => i as ItemExtended).ToArray();
I can do
using MyType = System.Collections.Generic.List<SomeClass.AClass>;
Now i only need MyType to be used within SomeClass. So i dont really need SomeClass to be public. However i can only do this outside of my namespace.
So how do i work this in such a way i can use MyType without making SomeClass and SomeClass.AClass public?
I don't see what this could gain you apart from saving keystrokes. If you want to do this to keep the option of easily replacing the List with another type of collection, then you can change the static types of the variable holding the collection to an appropriate interface.
That said, if you must go this way for some reason, there is always this option:
// Just to be used as a typedef
class MyType : System.Collections.Generic.List<SomeClass.AClass>
{
}
You can do this inside SomeClass.
I must do the following:
var someType = ObjectFactory.GetNamedInstance("myNamedInstance");
where someType can be any implementation of ICommand.
so I registered some of them:
For(typeof(ICommand<>)).Use(typeof(Command1)).Named("myNamedInstance1");
For(typeof(ICommand<>)).Use(typeof(Command2)).Named("myNamedInstance2");
is there a way to do this in StructureMap, because GetNamedInstance requires the type parameter which I don3t know until runtime.?
(For this, I'm assuming you created ICommand<T>)
This doesn't actually make any sense... think of the line:
//where aString is either myNamedInstance1 or myNamedInstance2
var someType = ObjectFactory.GetNamedInstance(aString);
Now assume that you are not going to use var, and instead the actual type. What would you put there that could compile? That is, what type can someType possibly be other than object?
Also, remember that ICommand<string> and ICommand<int> are both constructed types from ICommand<T>, but are not otherwise related - they have no common base type other than object.
If you don't the type until runtime, generics are not going to help a bunch - instead make your ICommand<T> inherit from some common interface - like ICommandBase - that has the methods you actually need.
However, if you just don't know the type in that method, you can push the unknown "up" in the compile by making the method containing that generic:
public void Execute<T>( string commandName)
{
var someType = ObjectFactory.GetNamedInstance<ICommand<T>>(commandName);
someType.Execute();
}
Now the caller of execute needs the type param... but again you could push that up. Notice that eventually you'll need the type parameter.
I have entity class generated by E-R designer that I have modified a little. This is declaration:
public abstract partial class Preference<T> : EntityObject, IPreference<T>
Then there is another entity class declared as follows:
public partial class BoolPref : Preference<bool>
so BoolPref inherits from Preferences<bool>.
Now I have this generated property:
public ObjectSet<Preference<object>> Preferences
{
get
{
if ((_Preferences == null))
{
_Preferences = base.CreateObjectSet<Preference<object>>("Preferences");
}
return _Preferences;
}
}
private ObjectSet<Preference<object>> _Preferences;
When I try to add new BoolPref to this ObjectSet as follows
context.Preferences.AddObject(new BoolPref ());
I get compile time error.
How can I add instances of BoolPref to Preferences ? Where is the mystake ?
Suppose Preference<T> has a read-write property called Value of type T. Now suppose the type system works the way you'd like it to:
var set = new ObjectSet<Preference<object>>();
set.Add(new Preference<bool>());
set.First().Value = "hello";
That's legal at compile time because set.First().Value has compile time type of object, not bool. But at runtime it is of type bool, and you just called a setter that takes a bool and passed a string, corrupting memory in the CLR which then crashes and dies horribly.
That's why this is not legal. In C# 4 you can have generic covariance and contravariance only if it is provably typesafe, and only if the generic type is an interface or delegate, and only if the varying type argument is of reference type.
The short answer is that generics, out of the box, don't handle polymorphism in the same way which "normal" objects handle polymorphism-- Preference<object> and Preference<bool> are two mutually incompatible occasions of Preference<T> not a supertype/subtype.
The good news is that with .NET 4.0, you can use covariance to get the desired effect.
The other issue here is I'm not sure how the EF is going to be able to handle your class in terms of persistence as it probably has no idea what to do with Preference<T>.
The way around this is to have an IPreference interface that exposes the underlying value as an Object, so you can have an ObjectSet<IPreference>. The Preference<T> explicit implementation of IPreference would then need to check at runtime whether it is being provided values that match the underlying type.